Переопределяющие свойства абстрактного класса - PullRequest
0 голосов
/ 10 апреля 2011

ODS List - это коллекция абстрактных классов, которые реализуют отфильтрованный метод выбора для источника данных постраничного / отсортированного объекта. Я определил три абстрактных класса, которые представляют фильтр, возвращаемые данные и методы, которые дают эти результаты:

[Serializable]
public abstract class ListFilter
{
    //  Define filter properties
}

[Serializable]
public abstract class ListData
{
    //  Define properties to be returned from the query
}
public abstract class ListMethods
{
    public int ListCount(ListFilter filter)
    {
        var rows = listQuery();
        rows = listFilter(rows, filter);
        return rows.Count();
    }

    /// <summary>
    /// List returns a page of data 
    /// </summary>
    /// <param name="filter"></param>
    /// <param name="sortType"></param>
    /// <param name="startRowIndex"></param>
    /// <param name="maximumRows"></param>
    /// <returns></returns>
    public IEnumerable<ListData> List(ListFilter filter, string sortType, int startRowIndex, int maximumRows)
    {
        var rows = listQuery();
        rows = listFilter(rows, filter);
        rows = listSort(rows, sortType);
        return rows.Distinct().Skip(startRowIndex).Take(maximumRows).ToList();
    }

    public abstract IQueryable<ListData> listQuery();

    public virtual IQueryable<ListData> listFilter(IQueryable<ListData> rows, ListFilter filter)
    {
        return rows;
    }

    public virtual IQueryable<ListData> listSort(IQueryable<ListData> rows, string sortType)
    {
        bool sortDescending = false;
        if (!string.IsNullOrEmpty(sortType))
        {
            string[] values = sortType.Split(' ');
            sortType = values[0];
            if (values.Length > 1)
            {
                sortDescending = values[1] == "DESC";
            }
        }


        if (!string.IsNullOrEmpty(sortType))
        {
            if (sortDescending)
            {
                rows = rows.OrderBy(sortType + " DESC");
            }
            else
            {
                rows = rows.OrderBy(sortType);
            }
        }

        return rows;
    }

}

Моя реализация сталкивается с проблемой, когда я пытаюсь привести ListData к явным возвращенным данным.

[Serializable]
public class EmployeeData : ODSList.ListData
{
    public int EmployeeId { get; set; }
    public int? ReportsToId { get; set; }...
}

    public override IQueryable<ListData> listQuery()
    {
        var dc = new NorthwindDataContext();
        var allrows = from emp in dc.Employees
                    select new EmployeeData()
                    {
                        EmployeeId = emp.EmployeeID,
                        ReportsToId = emp.ReportsTo, ...
                    };
        return (IQueryable<ListData>)allrows; <-- PROBLEM ENCOUNTERED HERE
    }

Диагностика, которую я нажал:

Невозможно привести объект типа 'System.Data.Linq.DataQuery 1[BusinessLayer.EmployeeData]' to type 'System.Linq.IQueryable 1 [ODSList.ListData]'.

Ответы [ 2 ]

0 голосов
/ 10 апреля 2011

Какую версию .Net вы используете? Если вы используете версию более раннюю, чем 4.0, типы, указанные в универсальном интерфейсе, являются инвариантными, что означает, что вы не можете преобразовать IQueryable в IQueryable.

Ознакомьтесь со статьей MSDN здесь .

edit: После нескольких экспериментов и поиска этого ТАК сообщения , я обнаружил, что что-то вроде следующего должно работать для вас:

public override IQueryable<ListData> listQuery()
{
    var dc = new NorthwindDataContext();
    var allrows = from emp in dc.Employees
                select new EmployeeData()
                {
                    EmployeeId = emp.EmployeeID,
                    ReportsToId = emp.ReportsTo, ...
                } as ListData;
    return allrows.OfType<ListData>();
}
0 голосов
/ 10 апреля 2011

Вы можете попробовать

return allrows.AsQueryable();

, и я не уверен, но вам может понадобиться

return allrows.Cast<ListData>().AsQueryable(); // if EmployeeData inherits from ListData; it is not required.
                                               // but i'm not sure if ListData is the same as ODSList.ListData
...