簡體   English   中英

實體框架相關數據外鍵

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM