Linq оставил соединение, добавив данные в левый объект - PullRequest
2 голосов
/ 12 февраля 2020

У меня есть 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 много свойств.

Как правильно это сделать?

1 Ответ

1 голос
/ 12 февраля 2020

Ваш код:

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

У вас уже есть Foo в качестве параметра, поэтому вы можете изменить делегата, в который вы передаете:

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

Исправьте меня, если я ошибаюсь , fooRepository возвращает List<Foo>, и после левого присоединения вы просто хотите дополнить их дополнительными данными из объединения.

ОБНОВЛЕНИЕ: На самом деле я ошибся, поскольку здесь у нас есть IQueryable, в котором Expression является параметром вместо делегата, и не может преобразовать лямбду с телом оператора в дерево выражений.

Теперь еще одна идея, которая не является лучшей, поскольку она будет использовать дополнительные итерации, но все же - это преобразовать в IEnumerable и выполнить Тот же трюк.

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