实体框架核心包含过滤器

leg*_*007 3 c# entity-framework entity-framework-core

我试图从数据库中带来一个具有子对象列表的对象列表.

这是一个例子

 public class User 
 {
    public int Id { get; set; }
    public ICollection<Child> Childs { get; set; }
 }

 public class Child 
 {
    public int Id { get; set; }
    public string UserId { get; set; }
    public User User { get; set; }
 }
Run Code Online (Sandbox Code Playgroud)

这里的问题是我无法找到一种方法来提供用户列表并同时过滤具有条件的Childs.

我试过这样的事情:

users = _context.Users.Where(e => e.Childs.Any(ec => ec.Id > 1))
Run Code Online (Sandbox Code Playgroud)

但是如果不满足条件,则使用此示例将不会使用户返回并且我希望所有用户即使他们没有Childs或者条件不满足也是如此.

还发现了这个项目:https://github.com/zzzprojects/EntityFramework-Plus但看起来它并不支持EF Core我想做的事情.

有没有人有任何建议?

谢谢

Jon*_*nan 8

免责声明:我是项目Entity Framework Plus的所有者

由于N + 1查询问题,我们的库不支持.NET Core的查询过滤器.

在我们的EF6引擎盖下,我们的图书馆只进行了简单的投影.

使用您的信息与此类似的东西:

var users = _Context.Users.Select(x => new {
                Users = x,
                Childs = x.Childs.Any(ec => ec.Id > 1)
            })
            .ToList()
            .Select(x => x.Users)
            .ToList();
Run Code Online (Sandbox Code Playgroud)

但是,对于EF Core,相同的投影会使数据库往返以获取每个用户的子项(N + 1个查询)

您可以尝试以下投影,看看是否得到相同的错误.

我相信,直到EF核心团队修复它,据我所知,没有办法过滤子实体.

SELECT [x].[Id], [x].[ColumnInt]
FROM [Lefts] AS [x]
go
exec sp_executesql N'SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [Rights] AS [ec1]
        WHERE ([ec1].[Id] > 1) AND (@_outer_Id1 = [ec1].[LeftId]))
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END',N'@_outer_Id1 int',@_outer_Id1=1
go
exec sp_reset_connection
go
exec sp_executesql N'SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [Rights] AS [ec1]
        WHERE ([ec1].[Id] > 1) AND (@_outer_Id1 = [ec1].[LeftId]))
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END',N'@_outer_Id1 int',@_outer_Id1=2
go
exec sp_reset_connection
go
exec sp_executesql N'SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [Rights] AS [ec1]
        WHERE ([ec1].[Id] > 1) AND (@_outer_Id1 = [ec1].[LeftId]))
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END',N'@_outer_Id1 int',@_outer_Id1=3
go
exec sp_reset_connection
go
exec sp_executesql N'SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [Rights] AS [ec1]
        WHERE ([ec1].[Id] > 1) AND (@_outer_Id1 = [ec1].[LeftId]))
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END',N'@_outer_Id1 int',@_outer_Id1=4
go
exec sp_reset_connection
go
exec sp_executesql N'SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [Rights] AS [ec1]
        WHERE ([ec1].[Id] > 1) AND (@_outer_Id1 = [ec1].[LeftId]))
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END',N'@_outer_Id1 int',@_outer_Id1=5
go
Run Code Online (Sandbox Code Playgroud)

答案子问题:

随着.NET Core 2.0的新版本,这个问题得到了修复吗?

不幸的是,Entity Framework仍然无法使用V2.x正确处理强制转换

例如,使用Cast方法的LINQ不起作用:

var ids = ctx.MyTables
    .Cast<IMyTable>()
    .Cast<MyTable>()
    .Where(x => x.SomeKey.Equals(keyId))
    .Select(x => x.MyFieldIntegerIWant)
    .ToList();
Run Code Online (Sandbox Code Playgroud)