【问题标题】:Lambda expression: Where clause for Include listLambda 表达式:包含列表的 Where 子句
【发布时间】:2013-04-04 20:10:50
【问题描述】:

所以我得到了这样的东西:

var myObj = db.SomeObject
              .Include("Tasks")
              .SingleOrDefault(x => x.Id == someObjectId);

if (myObj != null)
{
    myObj.Tasks = myObj.Tasks.OrderBy(x => x.Number).ToList();
}

在这里,我希望能够在我的 Include 上设置一个条件 (where),例如: .where task.IsDeleted == false

到目前为止,我还没有找到解决方案。

我知道我可以将where 与我订购任务的位置一起使用,但是这不会在数据库上运行,而是使用内存。我希望它在数据库上运行。

这里有人知道我该怎么做吗? 如果是这样,还有没有办法将order by 条件放入包含的任务列表中?

【问题讨论】:

  • 不认为这是可能的。
  • 你为什么不直接完成任务呢?然后只是没有任务的对象?
  • @sylon:你什么意思?

标签: c# linq lambda


【解决方案1】:

类似这样的东西,返回您的原始对象,其子集合已过滤和排序。

SomeObject a = db.SomeObjects.Where(x => x.Id == someobjectid)
                      .Select(
                          x =>
                          new
                              {
                                  someObject = x,
                                  task = x.Tasks.Where(task => task.IsDeleted == false)
                                                .OrderBy(task => whatever)
                              })
                      .Select(x => x.someObject).Single();

它实际上丢失了最后一次选择中的活动集合,所以你可以这样做:

SomeObject a = db.SomeObjects.Where(x => x.Id == someobjectid)
                      .Select(
                          x =>
                          new
                              {
                                  someObject = x,
                                  task = x.Tasks.Where(task => task.IsDeleted == false)
                                                .OrderBy(task => whatever)
                              });
 return a.FirstOrDefault().someObject;

【讨论】:

  • 这确实有效,并且确实给了我原始对象。谢谢!
【解决方案2】:

要做到这一点是 EF,您需要使用 Select 子句指定投影。

这样的东西只会从数据库中获取你想要的数据:

var anonymous = db.SomeObject.Where( x => x.Id == someObjectId )
  .Select( x => new
    {
      SomeObject = x,
      Tasks = x.Tasks
        .Where( o => !o.IsDeleted )
        .OrderBy( o => ... )
    }
  )
  .SingleOrDefault()
;

你最终会得到一个匿名类型的实例,但你可以很容易地在客户端上修复它:

MyObject myObject = anonymous.SomeObject;
myObject.Tasks = anonymous.Tasks;

【讨论】:

  • 这可能有效,只是用这个来测试一些东西。
  • 仅供参考 - 如果您不想处理匿名对象,您可以通过 .Select( x=> new YourModelClass 将其显式转换为 Select 中的模型
【解决方案3】:

简单的答案是:你不能那样做。

为什么?因为你查询SomeObject.
每个返回的SomeObject 都包含所有引用的数据,因为如果不这样,它就不能代表数据库中的实际对象。

【讨论】:

  • 那么更好的方法是什么?因为我有例如 1000 个任务并且我不想加载所有任务,因为例如 600 个将 IsDeleted 标志设置为 true
  • @Tikkes:我认为在这种情况下你想要一个投影。 Nicholas Butler 显示了 EF 的示例。
【解决方案4】:

分别获得它们怎么样:

var myObj = db.SomeObject
              .SingleOrDefault(x => x.Id == someObjectId);


var tasks = db.SomeObject
              .Where(x => x.Id == someObjectId)
              .SelectMany(x => x.Tasks)
              .Where(x => !x.Deleted);

【讨论】:

    猜你喜欢
    • 2017-05-29
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    相关资源
    最近更新 更多