EF5一对多导航属性映射

本文关键字:映射 属性 导航 一对多 EF5 | 更新日期: 2023-09-27 18:26:36

我搜索了又搜索,找不到任何能回答我问题的东西。

我有以下实体:

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对应的所有Jam。

非常感谢您的帮助!

EF5一对多导航属性映射

看起来您需要两个外键关系:一对多(item->nav)和多对多(nav<-->jam)。Nav/cam之间的映射不应该与项目有任何关系。

以下是我的设置方法:

将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; }
}

然后在导航和干扰类中设置many>many 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");
});

编辑!更新

刚刚看到您想要nav2jam表的创建时间。不幸的是,使用标准EF many-many 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 });