选择中的实体框架条件

本文关键字:框架 条件 实体 选择 | 更新日期: 2023-09-27 18:35:37

我有以下数据库代码:

static IEnumerable<dynamic> GetData(bool withchildren) {
    using (var model = new testEntities()) {
        var res = default(IQueryable<dynamic>);
        if (withchildren) {
            res = model.UserSet
                .Where(u => u.name != "")
                .Select(u => new {
                    Name = u.name,
                    Email = u.email,
                    Groups = u.GroupSet.Select(g => new {
                        Name = g.name,
                        Id = g.Id
                    })
                });
        } else {
            res = model.UserSet
                .Where(u => u.name != "")
                .Select(u => new {
                    Name = u.name,
                    Email = u.email
                });
        }
        return res.ToList()
    }
}

我想缩小代码并像这样写:

static IEnumerable<dynamic> GetData(bool withchildren) {
    using (var model = new testEntities()) {
        var res = default(IQueryable<dynamic>);
        res = model.UserSet
            .Where(u => u.name != "")
            .Select(u => {
                dynamic item = new { 
                    Name = u.name,
                    Email = u.email
                };
                if(withchildren) {
                    item.Groups = u.GroupSet.Select(g => new {
                        Name = g.name,
                        Id = g.Id
                    });
                }
                return item;
            });
        return res.ToList();
    }
}

但是Visual Studio抱怨说,它无法将lambda表达式转换为表达式树。

我的问题是,有没有办法用实体框架和 Linq 来实现这一点?我真的不想直接使用 ADO.net。

也许甚至有比我想象的代码更好的版本来缩小它。

下面是与 Linq-To-Objects 相关的问题。

编辑

在有人问之前,我在示例代码中使用dynamic以使其更容易、更快捷。

编辑 2

我使用此方法的目标是仅查询提高性能所需的字段。检查 http://www.progware.org/Blog/post/Slow-Performance-Is-it-the-Entity-Framework-or-you.aspx。

目前我们使用类似的东西

static IEnumerable<dynamic> GetData(bool withchildren) {
    using (var model = new testEntities()) {
        var res = default(IQueryable<dynamic>);
        res = model.UserSet
            .Where(u => u.name != "")
            .ToList();
        return res;
    }
}

根据Glimpse的说法,表演很糟糕。

编辑 3

简短的旁注,我编造了一些快速而肮脏的代码。也就是说,为什么最后不需要foreach。实际代码目前不可用。

选择中的实体框架条件

有什么

理由你不能使用:

res = model.UserSet
    .Where(u => u.name != "")
    .Select(u =>  new { 
            Name = u.name,
            Email = u.email,
            Groups = withchildren 
                ? u.GroupSet.Select(g => new {
                     Name = g.name,
                     Id = g.Id
                  })
                : null;
            })
        };

或者也许:

res = model.UserSet
    .Where(u => u.name != "")
    .ToList()                        // ToList() here to enumerate the items
    .Select(u => {
        dynamic item = new { 
            Name = u.name,
            Email = u.email
        };
        if(withchildren) {
            item.Groups = u.GroupSet.Select(g => new {
                Name = g.name,
                Id = g.Id
            });
        }
        return item;
    });

允许您消除某些代码的一种方法是:

var res = model.UserSet.Where(u => u.name != "");
if (withchildren) {
    res = res.Select(u => new {
             Name = u.name,
             Email = u.email,
             Groups = u.GroupSet.Select(g => new {
                Name = g.name,
                Id = g.Id
             })
          });
} else {
    res = res.Select(u => new {
            Name = u.name,
            Email = u.email
        });
}

社区功能最需要的功能之一是支持 EF 中的多行表达式,但是到目前为止,您只能使用条件运算符"?:"以及将结果包装在一种常见的类型,因此您的两个结果都必须具有"组"字段。

此外,还有对 linq 提供程序的扩展,例如 https://www.nuget.org/packages/LinqKit/,但是它们基于自己的约定,因此任何开发人员都应该在之前深入研究它提前应用和支持在该扩展上编写的代码。