重写抽象类的属性

发布于 2024-10-31 03:20:44 字数 2908 浏览 0 评论 0原文

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.DataQuery1[BusinessLayer.EmployeeData]”的对象转换为类型“System.Linq.IQueryable1[ODSList.ListData]”。

ODS List is a collection of abstract classes that implement a filtered select method for a paged/sorted object datasource. I have defined three absract classes that represent the filter, the returned data and the methods that produce these results:

[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;
    }

}

My implementation hits a problem when I try to cast the ListData to the explicit returned data.

[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
    }

The diagnostic I hit is:

Unable to cast object of type 'System.Data.Linq.DataQuery1[BusinessLayer.EmployeeData]' to type 'System.Linq.IQueryable1[ODSList.ListData]'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

桃气十足 2024-11-07 03:20:44

您使用什么版本的.Net?如果您使用的是 4.0 之前的版本,则通用接口中指定的类型是不变的,这意味着您无法从 IQueryable 转换为 IQueryable。

请在此处查看 MSDN 文章。

编辑:经过一番实验并找到 这篇 SO 帖子,我发现类似以下内容应该适合您:

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>();
}

What version of .Net are you using? If you're on a version earlier than 4.0 the types specified in a generic interface are invariant, meaning you can't cast from IQueryable to IQueryable.

Check out the MSDN article here.

edit: After a bit of experimenting and finding this SO post, I found that something like the following should work for you:

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>();
}
慵挽 2024-11-07 03:20:44

你可以尝试

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

You can try

return allrows.AsQueryable();

and I'm not sure but you may need to do

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文