将 lambda 参数传递给 include 语句

2023-11-30

我正在使用System.Data.Entity命名空间,因此我可以将 lambda 表达式传递给 Linq Include 方法。

public ICollection<MyEntity> FindAll()
    {
        using (var ctx = new MyEntityContext())
        {
            return ctx.MyEntity.Include(x => x.SomeLazyLoadedValue).ToList();
        }
    }

当我在不同的方法中使用Where语句时,我可以向它传递一个参数,如下所示:

public ICollection<MyEntity> FindAllBy(Func<MyEntity, bool> criteria)
    {
        using (var ctx = new MyEntityContext())
        {
            return ctx.MyEntity.Where(criteria).ToList();
        }
    }

然而,在 Include 中尝试同样的事情是行不通的:

public ICollection<MyEntity> FindAll(Func<MyEntity, bool> criteria)
    {
        using (var ctx = new MyEntityContext())
        {
            return ctx.MyEntity.Include(criteria).ToList();
        }
    }

如果你尝试这样做,Visual Studio 会抱怨它

Cannot convert from 'System.Func<MyEntity, bool>' to 'string'

如何将 lambda 传递给 Include 方法?


您的代码存在一些问题。例如,你的FindAllBy不执行sqlWHERE查询,而是加载数据库中的所有条目,然后根据您的数据在内存中进行过滤criteria。要理解为什么会这样,请看以下内容:

int a = 5;
long b = 5;

现在,这里发生的事情很明显,但仍然非常重要。编译器读取以下代码并生成两个变量。一个整数和一个长整型,其值都设置为数字 5。但是,这两个数字的值是不同的,即使它们(在源代码中)设置为相同的值。一种是 32 位,另一种是 64 位。

现在,我们来看看下面的代码:

Func<int, string> a = num => num.ToString();
Expr<Func<int, string>> b = num => num.ToString();

这里(或多或少)发生了同样的事情。在第一种情况下,C# 编译器认为您需要一个谓词(aFunc<int, string>谓词),而第二个值是Expr<Func<int, string>>即使值写成相同。然而,与第一个示例相反,这里的最终结果有很大不同。

谓词被编译为编译器生成的类上的方法。它的编译方式与任何其他代码一样,并且只允许您删除一堆样板文件。另一方面,表达式是实际编写的代码在内存中的表示。例如,在这种情况下,表达式可能类似于Call(int.ToString, $1)。这可以由其他代码读取并转换为 SQL 等,然后用于查询数据库。

现在,回到你的问题。 EntityFramework 为您提供帮助IQueryable<T>实例,进而继承IEnumerable<T>。每当您枚举可枚举对象时,它都会查询数据库。

所有接受委托的扩展方法都定义在IEnumerable从而查询你的数据库before运行谓词。这就是为什么您需要确保选择正确的方法重载。

编辑(回答评论)]
为了更清楚地说明这一点,我将举几个例子。比如说我们有一个User包含的类FirstName, LastName and Age,并且数据库集合被简单地称为db.

Expr<Func<User, bool>> olderThan10 = u => u.Age > 10;
Func<User, bool> youngerThan90 = u => u.Age < 90;
var users = db.Where(olderThan10).Where(youngerThan90);

这将导致 SQL 找到所有年龄超过 10 岁的用户,然后它会在内存中过滤掉所有年龄超过或等于 90 岁的用户。

所以通过一个Func并不一定意味着它查询整个数据库。这只是意味着它此时停止构建查询并执行它。

至于下一个问题,Expression<Func<T,bool>>不是一个普遍的答案。它的意思是“一个接受 T 并返回 bool 的表达式”。在某些情况下,比如.Include这引发了整个问题,你不想返回一个布尔值。您想要返回您想要包含的任何内容。例如,如果我们回到我们的用户示例,并修改Father用户类上引用另一个用户的属性,我们希望将其包含在常规代码中

db.Include(u => u.Father);

现在。这里,u是一个User,返回值u.Father也是一个用户,所以在这种情况下u => u.Father is Expr<Func<User, User>> or Expr<Func<User, object>>(不知道实体框架是否.Include接受通用值或简单地objects).

So your FindAll函数应该看起来像这样:

public ICollection<TData> FindAll<TInclude>(Expr<Func<TData, TInclude>> include) {
    using (var ctx = new TContext()) {
        return ctx.T.Include(include).ToList();
    }
}

不过,说实话,这是看起来很奇怪的代码,而且鉴于您(例如)已经命名了模型,您可能正在对模型做一些其他奇怪的事情T and TContext。我的猜测是您需要阅读一些有关 C# 中泛型如何工作的内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 lambda 参数传递给 include 语句 的相关文章

随机推荐

  • html5 canvas弹性碰撞方块

    我重新问这个问题是因为我在上一个问题中没有明确说明我想要什么 有谁知道如何使用矩形在 Canvas 中进行弹性碰撞或处理碰撞 或者能给我指出正确的方向吗 我创建了一个具有多个正方形的画布 并希望每个正方形在接触时发生偏转 这是我整理的一个快
  • 写入 selenium 数据时 CSV 为空

    我正在第一次体验 Selenium 并在一个著名的视频平台上做了一些教程 大多数时候它工作得相当可靠 但是 我遇到了一些问题 创建了 CSV 但未导出数据 CSV 被 触及 但它不会导出正常打印中显示的数据 谁能帮我看看这个脚本的问题出在哪
  • AngularJS 文本区域按 Enter 键换行

    我正在开发一个 AngularJS 应用程序 就像我们在 stackoverflow 上发布答案和问题一样 我们可以在文本区域下方实时预览答案或问题 这是我的试用代码 索引 html div div
  • FormData.get 函数未定义

    FormData get 在 Chrome 中未定义 https developer mozilla org en US docs Web API FormData get 默认情况下 Chrome 不支持 get 方法 以及delete
  • 使用 PDFBox 从 PDF 中读取某些 unicode 字符时出现问题

    我是 PDFBOX 新手 我正在阅读印地语的 PDF 文件 我在使用 PDFBox 从 PDF 中读取某些 unicode 字符时遇到问题 我想将字符串复制到 java 对象中 以便我可以处理它 我尝试了一些方法来读取文件 1 我尝试使用P
  • 如何在分组项目页面中每组之前插入图像列表?

    我目前正在使用 XAML 和 C 开发 Windows 8 应用程序 我开发了动态生成数据组的分组项目页面 我有一个社交媒体图标列表 我需要将其放在每个组标题旁边 但在左侧对齐 如屏幕截图所示 当我在 XAML 代码中添加列表时 它会在第一
  • Makefile c++11 支持

    我最近开始了一个 C 的小项目 我创建了一个简单的 Makefile CC g CFLAGS std c 0x I c VPATH src include vpath c src vpath h include TabooSearch ma
  • 如何在 Visual Studio 中连接到 MySQL 数据源

    我用MySQL 连接器 网络通过引用程序集 MySql Data dll 并传入连接字符串来连接到我的数据库MySqlConnection 我喜欢这样 因为我不需要安装任何东西 有没有办法在 Visual Studio 2010 中 选择数
  • 为什么我会遇到找不到类异常

    我在用DeferredTextImpl类和 eclipse 似乎没有抱怨它 但是当我运行我的项目时 我得到运行时异常 Class not found exception for DeferredTextImpl 当我搜索类文件时 我发现它在
  • 如何在 Objective C 中使用 AssetLibrary 检索视频的文件大小

    我想知道如何使用 AssetLibrary 检索视频的文件大小 有人能指出我正确的方向吗 或者可能有一些代码片段 这应该会让你走上正轨 看资产库框架参考 void logVideoSizes void assetEnumerator ALA
  • 为什么 xUnit Runner 找不到我的测试

    我有一个 xUnit net 测试如下 static class MyTestClass Fact static void MyTestMethod VS 2012 的 xUnit 插件说 没有发现可以运行的测试 TestDriven ne
  • ASP.NET MVC 中的 ELMAH 和异常管理

    我正在考虑从企业库中的异常管理应用程序块转移到新的 ASP NET MVC 站点 Scott Hansleman 在 ELMAH 上的帖子引起了我的注意 但我并不完全理解这种方法 通常 我会抑制一些异常 可恢复的异常 将它们记录在中央存储库
  • 在python中读取TDMS文件如何使用tdms info命令?

    我想知道Labview生成的tdms文件的内容是什么 按照此site 我用Python写 import numpy as np from nptdms import TdmsFile from nptdms import tdms read
  • 在外部网站上自动填写和提交表格

    我想知道一个人如何自动填写多个表格 使用bot local server 使用ajax或curl在外部站点 PHP 的多个页面上 例如一个网站www abc com index php有一个表格
  • 配置.vimrc时如何映射命令键?

    我使用 mac 我想配置 vimrc 例如 map
  • 模拟时间序列

    在最近的宏观经济预测在线课程中 有一个建模练习 y t 3 0 0 55 y t 1 e t where e t 定义为 et lt c 1 2138662 0 2854597 0 5902700 0 8285463 0 9954260 0
  • n 元函数的 Uncurry

    我有一个类型级别的数字 data Z deriving Typeable data S n deriving Typeable 和 n 元函数 来自固定向量包的代码 Type family for n ary functions type
  • 如何对 data.table 中的 .SD 列进行行明智操作

    虽然我之前已经弄清楚了这一点 但我仍然发现自己在 stackoverflow 上搜索 并且无法找到 这个语法 所以 我想对 data table 列的子集进行行明智操作 使用 SD and SDcols 我永远不记得手术是否需要sapply
  • Pandas 按组计算过去 n 天内发生的事件次数

    我有按 id 发生的事件表 如何计算过去 n 天内每种事件类型在当前行之前发生的次数 例如 事件列表如下 df pd DataFrame id 1 event day 2016 01 01 event type type1 id 1 eve
  • 将 lambda 参数传递给 include 语句

    我正在使用System Data Entity命名空间 因此我可以将 lambda 表达式传递给 Linq Include 方法 public ICollection