[英]Entity Framework Related Data Foreign Keys
我有一個只包含其他實體的外鍵的實體。 我的簡化類看起來像這樣:
DeliverNote
Adress add1 {get; set;}
Adress add2 {get; set;}
我可以自己加載地址,但是我無法加載DeliveryNote,因為我認為EF默認情況下不會加載相關數據。 所以我看到了解決方案,主要是context.notes.Include(dn => dn.Adresses),但我無法弄清楚我是如何告訴筆記或地址類它們是如何相互關聯的。 當我輸入“dn”時基本上。 沒有出現。
我看到的最簡單,可能正在工作的解決方案來自微軟。 在本頁的https://docs.microsoft.com/de-de/ef/core/querying/related-data的github中,您可以看到Blog和Post類。 對我來說,Post類看起來有缺陷,為什么帖子必須知道它所在的博客? 這將在代碼優先解決方案中弄亂數據庫。 如果同一篇文章將在幾個博客中發布怎么辦?
大多數解決方案似乎也是某種列表,我沒有列表,只是簡單的單個對象。 我認為1-1關系。
如果將模型定義為:
public class DeliverNote {
public int Id { get; set; }
public Adress addr1 { get; set; }
public Adress addr2 { get; set; }
}
public class Adress {
public int Id { get; set; }
}
然后你可以打電話:
context.notes.Include(dn => dn.addr1).Include(dn => dn.addr2);
其中將包括相關數據。
您的模型沒有為addr1或addr2定義外鍵,因此EF Core將為您創建陰影屬性,即表中存在但不作為c#模型中的屬性的列。
所以你有一個包含Addresses
表和DeliveryNotes
表的數據庫。 每個DeliveryNote
都有兩個Addresses
外鍵:一個From
和一個To
(你稱之為addr1和addr2)
如果你遵循實體框架代碼的第一個約定 ,你會有這樣的事情:
class Address
{
public int Id {get; set;}
... // other properties
// every Address has sent zero or more delivery Notes (one-to-many)
public virtual ICollection<DeliveryNote> SentNotes {get; set};
// every Address has received zero or more delivery Notes (one-to-many)
public virtual ICollection<DeliveryNote> ReceivedNotes {get; set};
}
class DeliveryNote
{
public int Id {get; set;}
... // other properties
// every DeliveryNote comes from an Address, using foreign key
public int FromId {get; set;}
public virtual Address FromAddress {get; set;}
// every DeliverNote is sent to an Address, using foreign key:
public int ToId {get; set;}
public virtual Address ToAddress {get; set;}
}
在實體框架中,表的列由非虛擬屬性表示。 虛擬屬性表示表之間的關系。
請注意,ICollection和FromAddress / ToAddress是虛擬的,因此不是列中的列。 如果需要,您可以將它們排除在課堂之外。 但是,如果您擁有這些虛擬屬性,則不必自己執行(組)連接。
我可以自己加載地址就好了,但我無法加載DeliveryNote,因為默認情況下EF不會加載相關數據...我
從中可以輕松地檢測出您想要的查詢類型。
數據庫查詢的一個較慢部分是將所選數據從DBMS傳輸到本地進程。 因此,最小化傳輸的數據是明智的。
如果使用Include
,則傳輸完整對象,包括外鍵和您不需要的所有屬性。 如果您有一個包含學校和學生的數據庫,那么每個學生都將擁有他所在學校的外鍵。 如果您使用Include要求“Id 1000他的學生”學校,使用Include,您不想將外鍵SchoolId運送1000次,因為您已經知道它將具有價值4
在實體框架中,如果要更改/更新已獲取的項目,則僅使用“包含”,否則使用“選擇”
給出一堆DeliveryNotes,給我一些AddressDetails:
IQueryable<DeliveryNote> deliveryNotes = dbContext.DeliveryNotes
.Where (deliveryNote => ...) // probably something with Id, or Date, or subject
.Select(deliveryNote => new
{
// select only the delivery note properties you actually plan to use
Subject = deliveryNote.Subject,
DeliveryDate = deliveryNote.DeliveryDate,
...
From = new
{
// select only the From properties you plan to use
Id = deliveryNote.FromAddress.Id,
Name = deliveryNote.FromAddress.Name,
Address = deliveryNote.FromAddress.Address,
...
}
To = new
{
// again: only properties you'll use
Name = deliveryNote.ToAddress.Name,
...
},
});
實體框架知道一對多關系,並將為您執行正確的連接。
鑒於一堆地址給了我一些他們收到的DeliveryNotes
var query = dbContext.Addresses
.Where(address => address.City == "New York" && ...)
.Select(address => new
{
// only properties you plan to use
Id = address.Id,
Name = address.Name,
ReceivedNotes = address.ReceivedNotes
.Where(note => note.DeliveryDate.Year == 2018)
.Select(note => new
{
// only properties you plan to use:
Title = note.Title,
...
// no need for this, you know it equals Id
// AddressId = note.FromId,
}),
});
實體框架知道一對多關系,並將為您做適當的groupjoin。
如果您有一對多的關系並且您想要“具有多個子項目的項目”,請從單側開始並使用虛擬ICollection。 如果您希望子項目包含它所屬的項目,請從多方面開始,並將虛擬屬性用於單側
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.