ASP.NET / LINQ / EF:自定义不同比较器类

时间:2017-01-26 15:19:12

标签: c# asp.net entity-framework linq

我正在使用带有EF Core的.NET Core。

我使用这样的自定义比较器类来实现查询的独特结果:

var filterResult = (from c in MyDBContext.Table1

                     join mt in MyDBContext.Table2
                     on c.ID equals mt.ID

                     select new MyModel
                     {
                         ID = c.ID,
                         Description = c.Description
                     }

                    )
                    .ToList()
                    .Distinct(new MyComparer())
                    .Take(takeThis);

这就是比较器类的样子:

public class MyComparer : IEqualityComparer<MyModel>
{

    public bool Equals(MyModel x, MyModel y)
    {

        return x.ID == y.ID;

    }

    public int GetHashCode(MyModel obj)
    {

        return obj == null ? 0 : obj.ID;

    }

}

这很有效,但我希望通过在distinct()之前运行ToList()来提高性能,以避免抓取整个表(并实现异步)。

这是我的目标:

var filterResult = await (from c in MyDBContext.Table1

                     join mt in MyDBContext.Table2
                     on c.ID equals mt.ID

                     select new MyModel
                     {
                         ID = c.ID,
                         Description = c.Description
                     }

                    )
                    .Distinct(new MyComparer())
                    .Take(takeThis)
                    .ToListAsync(); 

使用此功能,我得到NotSupportedException例外。所以我尝试做以下事情:

.Distinct(new MyComparer())
.Take(takeThis)
.ToList();

但这也给了我一个NotSupportedException例外。

如何更改代码以避免在不同之前运行ToList()

1 个答案:

答案 0 :(得分:0)

在EF查询的上下文中查询实现(.ToList())之前运行Distinct将导致EF将代码转换为SQL查询,但EF并不是将任何c#方法转换为SQL查询的强大功能,以下是Comparer逻辑。

作为此查询的替代方案,我建议您使用以下查询:

.GroupBy(x => x.ID)
.Select(g => g.OrderBy(x => x.ID).FirstOrDefault())
.OrderBy(x => x.ID)
.Take(() => ....)
.ToListAsync()

这将为具有相同ID的实体创建组,然后从每个组中选择第一个,并使用order by将保持查询的结果一致。