首页 > 解决方案 > Linq左连接将数据添加到左对象

问题描述

我有 3 个实体:

class Foo {
  public Guid? BarId { get; set; } //Has optional bar

  [NotMapped]
  public boolean? HasXyzzy { get; set; }
}

class Bar {
  ...
}

class Xyzzy {
  public Guid BarId { get; set; } //Always has Bar
}

我想Foo从数据库中检索一些并填写他们的HasXyzzy属性。我正在使用 LINQ 到实体扩展方法。

我在想这样的事情:

var xyzzys = xyzzyRepository.GetAll(); //IQueryable

var foos = fooRepository.GetAll()
    .Where() //Some condition
    .SelectMany(
        foo => xyzzys.Where(xyzzy => xyzzy.BarId == foo.BarId).DefaultIfEmpty(),
        (foo, xyzzy) => new Foo {
            BarId = foo.BarId,
            HasXyzzy = xyzzy != null
        });

但这很乏味,因为我的 Foo 类有很多属性。

这样做的正确方法是什么?

标签: c#linqlinq-extensions

解决方案


你的代码:

 (foo, xyzzy) => new Foo {
                BarId = foo.BarId,
                HasXyzzy = xyzzy != null
            });

您已经有一个 Foo 作为参数,因此您可以更改您传入的委托:

 (foo, xyzzy) =>
 { 
     foo.HasXyzzy = xyzzy;
     return foo;
 });

如果我错了,请纠正我,fooRepository 带来了List<Foo>,在左加入后,你只想用加入的额外数据来完成它们。

更新: 实际上我错了,因为我们这里有 IQueryable,它有 Expression 作为参数而不是委托,并且不能将带有语句体的 lambda 转换为表达式树。

现在,另一个想法不是最好的,因为它将使用额外的迭代,但仍然 - 是转换为 IEnumerable 并执行相同的技巧。

    (foo, xyzzy) => new {
                   foo, xyzzy                   
                }).AsEnumerable()
.Select(x=> 
{ 
     foo.HasXyzzy = xyzzy;
     return foo;
});

推荐阅读