Как жаль, что вы забыли дать нам ваши классы и ваши спецификации!
После попытки понять ваш SQL, кажется, что table1
имеет AssetStructureId
, чтовнешний ключ к Table2
, к которому принадлежит Table1
.Вероятно, отношение «один ко многим».
Table2
имеет внешний ключ Table3Id
к Table3
, к которому принадлежит ваш Table2
, также отношение «один ко многим»
Наконец Table3
имеет внешний ключ Table4Id
для Table4
, к которому принадлежит Table3
.
Мое, вы любите собственные имена для своих идентификаторов, не так ли?
Итак:
- Каждый
Table4Element
имеет ноль или более Table3Elements
; - Каждый
Table3Element
имеет ноль или более Table2Elements
; - Каждое
Table2Element
имеет ноль или более Table1Elements
.
В соответствии с соглашениями по коду, принятыми в коде сущности , у вас будут классы, подобные:
class Table4Element
{
public int Id {get; set;}
// every Table4Element has zero or more Table3Elements:
public virtual ICollection<Table3Element> Table3Elements {get; set;}
... // other properties
}
class Table3Element
{
public int Id {get; set;}
// every Table3Element has zero or more Table2Elements:
public virtual ICollection<Table2Element> Table2Elements {get; set;}
// every Table3Element belongs to exactly one Table4Element using foreign key
public int Table4ElementId {get; set;}
public virtual Table4Element Table4Element {get; set;}
...
}
В структуре сущностей столбцы ваших таблиц представлены не виртуальными свойствами;виртуальные свойства представляют отношения между таблицами.
Table2
и Table1
похожи:
class Table2Element
{
public int Id {get; set;}
// every Table2Element has zero or more Table1Elements:
public virtual ICollection<Table1Element> Table1Elements {get; set;}
// every Table2Element belongs to exactly one Table3Element using foreign key
public int Table3ElementId {get; set;}
public virtual Table3Element Table3Element {get; set;}
...
}
class Table1Element
{
public int Id {get; set;}
// every Table1Element belongs to exactly one Table2Element using foreign key
public int Table2ElementId {get; set;}
public virtual Table2Element Table2Element {get; set;}
...
}
И, наконец, ваши DbContext
:
class MyDbContext : DbContext
{
public DbSet<Table1Element> Table1Elements {get; set;}
public DbSet<Table2Element> Table2Elements {get; set;}
public DbSet<Table3Element> Table3Elements {get; set;}
public DbSet<Table4Element> Table4Elements {get; set;}
}
Это все, что необходимо для определения структуры таблиц и столбцов и связей между таблицами.Если по какой-то причине вам нужны другие имена таблиц или столбцов, вам нужно добавить атрибуты или использовать свободный API.
Самое важное в этом - то, что вы правильно указали свои виртуальные свойства.
Всякий раз, когда вы используете виртуальные свойства, структура сущностей знает, что требуется (групповое) объединение, и сделает их для вас
Теперь, когда мы определили ваши четыре таблицы, мы можем перейти
Вернуться к вашему вопросу
Упс, вы забыли указать, что хотите выбрать!
Ну, очевидно, на одном из ваших четырех столов есть Title
.Хотя вы этого не сказали, я думаю, что Title
является свойством Table1
.Кажется, у вас есть Id
из Table1Element
, который вы хотите выбрать Title
из Table4
, которому принадлежит Table1Element
Ввод: RequestedId
= 21803
- Table4Element с идентификатором A имеет
Title
- Table3Element с внешним ключом Table4ElementId A имеет идентификатор B
- Table2Element с внешним ключом Table3ElementId B имеет идентификатор C
- Table1Element с внешним ключом Table3ElementId C имеет идентификатор 21803
, который вы хотите Title
.
Использование виртуальных свойств делает запрос простым.Entity Framework сделает для вас объединения:
int requestedId = 21803;
var requestedTitle = myDbContext.Table1Elements // from all Table1 elements
.Where(table1Element => table1Element.Id = requestedId) // keep the one with the requestedId
.Select(table1Element = table1Element // and select the Title
.Table2Element // of the Table4 element
.Table3element // that it belongs to
.Table4Element
.Title)
.FirstOrDefault(); // You know there is only one
Очень интуитивно понятный и простой для понимания.
Не знаю почему, но некоторые люди настаивают на том, чтобы эти объединения выполнялись сами.Используя синтаксис метода, соединение с четырьмя таблицами выглядит ужасно:
int requestedId = 21803;
var requestedTitle = myDbContext.Table1Elements // from all Table1Elements
.Where(table1Element => table1Element.Id = requestedId) // keep the one with the requestedId
.Join(myDbContext.Table2Elements, // join with Table2Elements
table1Element => table1Element.Table2ElementId, // from Table1 take the foreign key
table2Element => table2Element.Id, // from Table2 take the primary key
(table1Element, table2Element) => table2Element) // when they match keep the Table2
.Join(myDbContext.Table3Elements, // to join with Table3
table2Element => table2Element.Table3ElementId, // foreign key to Table3
table3Element => table3Element.Id, // primary key
(table2Element, table3Element) => table3Element) // keep table3Element
.Join(myDbContext.Table4Elements, // to join with Table4
table3Element => table3Elemen.Table4ElementId, // foreign key
table4Element => table4Element.Id, // primary key
(table3Element, table4Element) => table4Element.Title) // keep the Title
.FirstOrDefault(); // expect only one element
Используя синтаксис запроса, этот запрос проще , но все же не так прост и интуитивно понятен, как использование виртуальных свойств.Тем не менее, вы должны убедить своего начальника в том, что выбранный вами метод лучше всего понять, протестировать и поддерживать