2015-05-12 30 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查询的问题,但是谢谢! –