实体或复杂类型''无法在LINQ to Entities查询中构造,三表外连接

时间:2017-08-04 15:38:23

标签: c# entity-framework linq

我在堆栈上看到了一些相关的问题,但不知道如何解决我的问题,因为我做了三个表左外连接。 RoleUserRole是实体对象

var query = from u in Context.Users
            join ru in Context.RoleUsers on u.Id equals ru.UserId into plv
            from x in plv.DefaultIfEmpty(new RoleUser())
            join r in Context.Roles on x.RoleId equals r.Id into pii
            from y in pii.DefaultIfEmpty(new Role())
            orderby u.Id, y.Id
            select new UserWithRole() { Id = u.Id, User = u, Role = y };

2 个答案:

答案 0 :(得分:1)

由于错误解释了您无法在linq查询中创建,因此他们映射了类型(RoleUserRole)。而是使用DefaultIfEmpty()。以下内容:

var roles = from ru in Context.RoleUsers 
            join r in Context.Roles on ru.RoleId equals r.Id
            select new { ru.UserId, role = r };

var query = from u in Context.Users
            join r in roles on u.Id equals r.UserId into plv
            from x in plv.DefaultIfEmpty()
            select new UserWithRole() { Id = u.Id, User = u, Role = x.role };

但是,我建议查看导航属性 - 这样您就不必构建连接并使用它,就好像它是正常的"对象。

答案 1 :(得分:1)

问题是DefaultIfEmpty(new RoleUser())DefaultIfEmpty(new Role())调用,因为EF无法将常量实体对象的创建转换为SQL。

因此,您需要使用DefaultIfEmpty()的无参数重载,并在具体化查询结果中处理null个对象。

如果您不需要IQueryable<T>结果,可以使用中间匿名类型投影,使用AsEnumerable()进行LINQ to Objects上下文并进行最终所需投影:

var query = (from u in Context.Users
             join ru in Context.RoleUsers on u.Id equals ru.UserId into userRoles
             from ru in userRoles.DefaultIfEmpty()
             join r in Context.Roles on ru.RoleId equals r.Id into roles
             from r in roles.DefaultIfEmpty()
             orderby u.Id, r.Id
             select new { User = u, Role = r }
            )
            .AsEnumerable() // db query ends here
            .Select(x => new UserWithRole
            {
                Id = x.User.Id,
                User = x.User,
                Role = x.Role ?? new Role() // now this is supported
            });