Как применить двухуровневый SelectMany с использованием выражений общим способом в C#C#

Место общения программистов C#
Ответить
Anonymous
 Как применить двухуровневый SelectMany с использованием выражений общим способом в C#

Сообщение Anonymous »

Давайте создадим три объекта с одним и тем же базовым классом для идентификаторов:

Код: Выделить всё

public class EntityBase
{
public int Id { get; set; }
}

public class Company : EntityBase
{
public string Brand { get; set; }
public List Factories { get; set; }
}

public class Factory : EntityBase
{
public string Location { get; set; }
public Company Company { get; set; }
public List Products { get; set; }
}

public class Product : EntityBase
{
public string Name { get; set; }
public Factory Factory { get; set; }
}
Из приведенного выше кода вы можете увидеть связи: Теперь я хочу получить простой список пар идентификаторов:

Например:
, ,
Означает:
  • Компания с ID=3 предоставляет продукцию с ID=5 и ID=6.
  • Компания с ID=7 предоставляет продукцию с ID=2
I можете подумать об этом выражении LINQ (предположим, мы используем EF Core):

Код: Выделить всё

var companiesProducts = dbContext.Set
.SelectMany(c => c.Factories, (c, f) => new { Company = c, Factory = f })
.SelectMany(cf => cf.Factory.Products, (cf, p) => new { CompanyId = cf.Company.Id, ProductId = p.Id })
.ToList();
Ну, я бы хотел сделать это немного «универсальным для C#». В моем реальном проекте есть много сущностей с похожими отношениями. Я не хочу писать этот сложный запрос несколько раз.
Если бы существовало только одно отношение «один ко многим», скажем, между Factory и Product, я мог бы представить такой метод:

Код: Выделить всё

public List GetIdPairs(
Expression subEntitySelector
) where TEntity : EntityBase where TSubEntity : EntityBase
{
var entitiesSubEntities = dbContext.Set
.SelectMany(subEntitySelector, (e, s) => new { EntityId = e.Id, SubEntityId = s.Id })
.ToList();

// Transformation from the  anonymous type to (int EntityId, int SubEntityId) tuple
var idPairs = ...

return idPairs;
}
Для простоты я не включил преобразование в правильный тип возвращаемого значения метода.
Теперь, когда у нас есть готовый метод, мы можем вызвать его следующим образом:

Код: Выделить всё

var factoryAndProductIds = GetIdPairs(f => f.Products);
Я хотел бы сделать то же самое для двухуровневой связи «один ко многим», но я действительно не знаю, как это сделать.
Есть предложения?

Подробнее здесь: https://stackoverflow.com/questions/798 ... ay-in-c-sh
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»