【问题标题】:Deferred loading in Entity Framework using DTO使用 DTO 在实体框架中延迟加载
【发布时间】:2014-04-28 02:11:27
【问题描述】:

我对使用实体框架的延迟加载功能一直面临的这个问题感到非常困惑。 我知道触发数据库查询的扩展,如 .ToList()、.Count() 等。 我的问题是,如果您使用 IEnumerable DTO 作为返回类型,这会触发数据库查询吗?

例如,您有以下 DTO:

public DtoUser
{
   public string Name { get; set; }
   public int Age { get; set; }
}

我在你的业务层有这个方法:

public BLLUser
{
   public IEnumerable<User> GetAllUser
   {
      var output = from u in context.User
                   select new DtoUser
                   {
                      Name = u.Name,
                      Age = u.Age
                   };
   }
}

我将其称为:

private void GetUserOnBll()
{
    using (BLLUser b = new BLLUser())
    {
       var dtoUser = b.GetAllUser();

       // can I still do this without triggering the database query
       // or the query is already been triggered
       // since the return type is an IEnumerable DTO
       var filtered = dtoUser.Where(n => n.Name == "TEST");
    }
}

“b.GetUser()”方法会触发数据库查询还是我必须使用 .ToList() 来触发查询?

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    b.GetUser() 不会触发数据库查询,dtoUser.Where(n =&gt; n.Name == "TEST") 也不会触发查询。不同的执行意味着它只会在你“使用”它时执行数据库查询,例如 foreach 子句或 SingleOrDefault()/Count()/...

    所以你上面的程序会做你想做的事。但是会有性能问题。生成的 SQL 会喜欢 Select Name, Age from User 它将所有记录从数据库中获取到内存中,在内存中进行过滤,然后返回过滤后的记录。如果要在数据库端进行过滤,应将 IEnumerable 替换为 IQueryable

    【讨论】:

    • 嗨,泰迪,你的解释真的很棒!它有助于清除我脑海中的所有乌云!只是跟进,这是一个经验法则,即使用 IEnumerable 作为返回类型将在过滤之前首先检索所有记录?
    • @arvstracthoughts 并非总是“所有”记录,这取决于您的代码。可以说,ASEnumberable() 之后的所有过滤条件都不会在数据库端应用。例如:context.User.Take(10).AsEnumberable().Take(2); ==> 将从数据库中检索前 10 条记录到内存中,然后返回前 2 条。
    【解决方案2】:

    创建 DtoUser 列表的属性

    并通过在构造函数中调用您的函数来分配值。如果您需要示例代码,请告诉我。

    另一件事我不知道您如何调用和获取我建议使用 IQueryable 而不是 IEnumerable 的上下文,因为数据库中的 IQueryable 句柄和服务器内存中的 IEnumerable 句柄。

    问候 普布都

    【讨论】:

      猜你喜欢
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多