C # Join по Linq, как должно пройти innerKeySelector? - PullRequest
0 голосов
/ 05 ноября 2018

как должен пройти innerKeySelector?

есть:

model1 - {int model1 Id, int model2Id, model2 Model2}
model2 - {int model2Id, List<model1> modelsRef, ...(other)}

нужно сделать:

query.Join(context.model2, x => x.Model2, y => y.modelsRef, (x,y) => new{
                Id = x.mdel1Id,
                (other)...}).Select();

есть ошибка компиляции:

{
    ...
    "message": "The type arguments for method 'Enumerable.Join<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, TInner, TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. [ProjectName]",

}

1 Ответ

0 голосов
/ 06 ноября 2018

Итак, у вас есть последовательность Model2s, где каждый Model2 имеет ноль или более Model1s. Каждый Model1 принадлежит ровно одному Model2 с использованием внешнего ключа Model1Id, довольно стандартного отношения «один ко многим».

При использовании платформы сущностей у вас будет что-то похожее на:

class Model2
{
    public int Id {set; set;}

    // every Model2 has zero or more Model1s:
    public virtual ICollection<Model1> Model1s {get; set;}

    ...
}

class Model1
{
    public int Id {set; set;}

    // every Model1 belongs to exactly one Model2, using foreign key
    public int Model2Id {get; set;}
    public virtual Model2 Model1 {get; set;}
    ...
}

Помните:

В структуре сущностей столбцы таблиц представлены не виртуальные свойства классов. Виртуальные свойства представляют отношения между таблицами.

Примечание: я изменил ваш List<Model1> Model1s на ICollection<Model1> Model1s. В конце концов, вы уверены, что это список? Что бы Model1s[4] значило?

Вы хотите объединить model1s и model2s, используя стандартное внутреннее соединение:

var result = dbContex.Model1s
    .Join(dbContext.Model2s,   // join Model1s and Model2s
    model1 => model1.Model2Id, // from every Model1 take the foreign key Model2Id
    model2 => model2.Id,       // from every Model2 take the primary key Id
    (model1, model2) => new    // when they match use the matching models to create
    {                          // a new object with the following properties
        SomeProperty = model1.PropertyA,
        SomeOtherProperty = model2.PropertyB,
        MyX = model2.PropertyC,
        MyY = model1.PropertyD,
        ....
    });

Используйте виртуальные свойства вместо Joins!

Несколько человек отметили, что вам не нужно использовать объединения при использовании платформы сущностей. Они правы. Вы можете получить тот же результат, используя коллекции. Результат кажется более естественным и более читабельным:

var result = dbContext.Model1s.Select(model1 => new
{
     SomeProperty = model1.PropertyA,
     SomeOtherProperty = model1.Model2.PropertyB,
     MyX = model1.Model2.PropertyC,
     MyY = model2.PropertyD,
});

Платформа сущностей знает ваши отношения один-ко-многим и сделает для вас внутреннее соединение.

Чтобы сделать GroupJoin:
Если у вас есть отношения один-ко-многим «родители-дети» и вам нужны определенные «родители со всеми или некоторыми из их детей», то начните с «Родителя» и используйте ICollection, чтобы получить детей. Это станет GroupJoin .

Для внутреннего присоединения
Если вам нужны «Дети с их родителями», начните с «Ребенка» и используйте свойство «Родитель». Это станет внутренним соединением

...