EF5一对多导航属性映射

时间:2014-10-15 06:40:17

标签: c# entity-framework entity-framework-5

我搜索并搜索过,找不到任何能回答我问题的内容。

我有以下实体:

public class Item
{
   public int ItemID { get; set; }
   public string Name { get; set; }
   public string Description { get; set; }
   public int? NavID { get; set; }
   public ICollection<NavJamMap> NavJamMaps { get; set; }
}

public class Nav
{
  public int NavID { get; set; }
  // stuff
}

public class Jam
{
  public int JamID { get; set; }
  // stuff
}

public class NavJamMap
{
  public int NavID { get; set; }
  public int JamID { get; set; }
  public DateTime CreateDate { get; set; }
  public Nav Nav { get; set; }
  public Jam Jam { get; set; }
}

使用以下流畅的映射:

modelBuilder.Entity<Item>().HasKey(i => i.ItemID);
modelBuilder.Entity<Item>().HasMany(i => i.NavJamMaps)
            .WithOptional()
            .HasForeignKey(m => m.JamID);

modelBuilder.Entity<Nav>().HasKey(n => n.NavID);
modelBuilder.Entity<Jam>().HasKey(j => j.JamID);
modelBuilder.Entity<NavJamMap>.HasKey(m => new { m.NavID, m.JamID });

基本上,我希望能够选择:

var item = ctx.Items.Where(i => i.NavJamMaps.Any(m => m.JamID == 10)).FirstOrDefault()

但它会生成如下SQL:

WHERE  EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[NavJamMap] AS [Extent47]
    WHERE ([Project20].[ItemID] = [Extent47].[NavID]) AND 
          ([Extent47].[JamID] = @p__linq__2)
)

如何更改我的流畅映射以允许我生成正确的SQL。我想加入Item实体上的NavID属性,并在ICollection中找到与该NavID对应的所有Jams。

任何帮助都非常感谢!

1 个答案:

答案 0 :(得分:1)

看起来你需要两个外键关系:一对多(item-&gt; nav)和多对多(nav&lt; - &gt; jam)。导航/果酱之间的映射不应与物品有关。

以下是我如何设置它:

将Item类更改为只有FK到Nav

public class Item
{
   public int ItemID { get; set; }
   public string Name { get; set; }
   public string Description { get; set; }
   public int? NavID { get; set; }
   public Nav? Nav { get; set; }
}

然后在Nav和Jam类中设置多个&gt;多个FK

public class Nav
{
    public ICollection<Jam> Jams {get;set;}
}

public class Jam
{
    public ICollection<Nav> Navs {get;set;}
}

然后为两种关系设置Fluent映射:

modelBuilder.Entity<Item>().HasOptional(x => x.Nav).WithMany().HasForeignKey(x => x.NavID).WillCascadeOnDelete(false);

modelBuilder.Entity<Nav>().HasMany<Jam>(x => x.Jams).WithMany(x => x.Navs).Map( x =>
{
    x.MapLeftKey("JamID");
    x.MapRightKey("NavID");
    x.ToTable("NavJamMap");
});

修改! UPDATE!

刚看到你想要nav2jam表的创建时间。不幸的是,使用标准的EF很多EntityConfiguration无法做到这一点。但是,您可以创建具有两个单独的一对多关系的单独联结表。

public class Nav
{
    public virtual ICollection<NavJamMap> NavJamMaps {get;set;}
}
public class Jam
{
    public virtual ICollection<NavJamMap> NavJamMaps {get;set;}
}

public class NavJamMap
{
    public int NavID {get;set;}
    public int JamID {get;set;}
    public Nav Nav {get;set;}
    public Jam Jam {get;set;}
    public DateTime CreationDate {get;set;}
}

然后使用映射:

modelBuilder.Entity<NavJamMap>().HasKey(x => new { x.NavID, x.JamID });