2015-05-12 33 views
2

我正在處理一個涉及遺留數據庫模式的項目,並且在嘗試使用實體框架(v6)加載相關實體時遇到了問題。這裏是正在使用的數據模型的一個簡單的例子:在實體框架中沒有顯式外鍵的負載相關實體

public partial class Product { 
    public virtual Delivery Delivery { get; set; } 
    public virtual string OrderNumber { get; set; } 
    public virtual int? VersionNumber { get; set; } 
    public virtual string SocialNumber { get; set; } 
} 

public partial class Delivery { 
    public virtual string OrderNumber { get; set; } 
    public virtual int? VersionNumber { get; set; } 
    public virtual string SocialNumber { get; set; } 
} 

我試圖實現與給定SocialNumber檢索的Product秒的名單時,包括相關的Delivery。當滿足以下條件時,DeliveryProduct相關:product.OrderNumber == delivery.OrderNumber && product.VersionNumber == delivery.OrderNumber && product.SocialNumber == delivery.SocialNumber

最簡單的方法是打電話Include。然而,由於EF聲稱product.Delivery不是有效的導航屬性,所以這似乎是不可能的。我試圖通過投影來獲得想要的結果,但失敗了。如果有人能解釋最好的EF/LINQ方法來獲得Product s(+他們的相關Delivery)與給定的SocialNumber,我會很感激。


更新:我想我應該闡述一些。


主要問題是我正在處理的遺留數據庫沒有顯式(複合)鍵在每個表上。例如,DeliveryProduct類映射到沒有主鍵的表。因爲EF需要主鍵,虛設鍵被定義如下:

dbModelBuilder.Entity<Product>().hasKey(pk => new { pk.OrderNumber }); 

實體類是由碼發生器產生,所以添加註釋沒有我正在尋找解決方案。我想應該可以通過DbModelBuilder來定義這些東西,但我不知道如何去做。


更新:想出一個解決方案。


預期(只顯示LINQ查詢應提供產品的對和相關交貨)以下查詢功能:

from data in _dartz3Context.V_VOV_GBA_DATAs 
join delivery in _dartz3Context.VOV_GBA_AANLEVERINGs 
    on new { Bsn = data.MunicipalBasicAdministrationSocialSecurityNumber, Version = data.VersionNumber, PolicyNumber = data.InsurancePolicyNumber } 
    equals new { Bsn = delivery.MunicipalBasicAdministrationSocialSecurityNumber, Version = delivery.VersionNumber, PolicyNumber = delivery.InsurancePolicyNumber } 
where data.MunicipalBasicAdministrationSocialSecurityNumber == socialSecurityNumber 
select new { Data = data, Delivery = delivery } 
+3

在EF模型中添加導航屬性。缺少正確的外鍵並不妨礙您在模型中創建導航屬性。 –

+0

是不是''Product.Delivery''已經是一個導航屬性? –

+0

由於缺少外鍵,您可能需要指定組成關係的關鍵字。鑑於它是一個多部分的密鑰,我不確定這會起作用,但可以嘗試在標識「OrderNumber」,「VersionNumber」和「SocialNumber」的'Delivery'屬性中添加三個'[ForeignKey]'屬性作爲外鍵。 –

回答

1

您需要定義使用註釋您的實體複合鍵或流利API:

public partial class Product { 
    [Key, Column(Order = 0)] 
    public virtual string OrderNumber { get; set; } 
    [Key, Column(Order = 1)] 
    public virtual int? VersionNumber { get; set; } 
    [Key, Column(Order = 2)] 
    public virtual string SocialNumber { get; set; } 
} 

public partial class Delivery { 
    [Key, Column(Order = 0), ForeignKey("Product")] 
    public virtual string OrderNumber { get; set; } 
    [Key, Column(Order = 1), ForeignKey("Product")] 
    public virtual int? VersionNumber { get; set; } 
    [Key, Column(Order = 2), ForeignKey("Product")] 
    public virtual string SocialNumber { get; set; } 
} 

http://www.codeproject.com/Articles/813912/Create-Primary-Key-using-Entity-Framework-Code-Fir

Fluent API版本:

// Composite primary key 
modelBuilder.Entity<Product>().HasKey(d => new { d.OrderNumber, d.VersionNumber, d.SocialNumber }); 

// Composite foreign key 
modelBuilder.Entity<Delivery>() 
    .HasRequired(c => c.Product) 
    .WithMany(d => d.Delivery) 
    .HasForeignKey(d => new { d.OrderNumber, d.VersionNumber, d.SocialNumber }); 
+0

不幸的是,使用註解不是我正在尋找的解決方案。實體類是用代碼生成器生成的,我寧願不改變這些類中的東西。我更新了OP,並對問題進行了更詳細的闡述。 –

+0

查看流利api的編輯 –

+0

感謝您的回答。你所描述的方法給出了正確的結果。實際上解決了OP中LINQ查詢的問題,但是謝謝! –