實體框架7 AddRange()不添加外部實體

c# entity-framework entity-framework-core

我一直在使用EF Code First,但這是我第一次使用EF7。

我有以下Model類,其中Venue與Show有一對多的關係:

public class Show
{
    public int Id { get; set; }
    public Venue Venue { get; set; }
    //...
}

public class Venue
{
    public int Id { get; set; }
    public string Name {get; set; }
    //...
    public List<Show> Shows { get; set; }
}

我像這樣設置DBContext:

public class NettlesContext : DbContext
{
    public DbSet<Show> Shows { get; set; }
    public DbSet<Venue> Venues { get; set; } 

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        new ShowConfiguration(builder.Entity<Show>());
        new ImageConfiguration(builder.Entity<Image>());
    }
}

public class ShowConfiguration
{
    public ShowConfiguration(EntityTypeBuilder<Show> builder)
    {
        builder.Property(p => p.Id).IsRequired();
        builder.Property(p => p.Title).IsRequired();
    } 
}

public class VenueConfiguration
{
    public VenueConfiguration(EntityTypeBuilder<Venue> builder)
    {
        builder.Property(p => p.Id).IsRequired();
        builder.Property(p => p.Name).IsRequired();
    }
}

然後在一些啟動代碼中我初始化數據庫,如下所示:

    private static void AddShows(NettlesContext db)
    {
        var shows = new List<Show>()
        {
            new Show()
            {
                Title = "Portland Country Dance Community Contra Dance",
                Venue = new Venue()
                {
                    Name = "Fulton Community Center",
                },
            },
            new Show()
            {
                Title = "Portland Roadhouse Contra Dance",
                Venue = new Venue()
                {
                    Name = "Milwaukie Community Club",
                },
            },
        };

        db.Shows.AddRange(shows);
        db.SaveChanges();
    }

除了VenueId為null之外,才會正確初始化Shows表。 Venue表完全是空的。

這是怎麼回事?

一般承認的答案

DbSet.Add有第二個參數。

Add(TEntity entity, GraphBehavior behavior = GraphBehavior.IncludeDependents)

雖然默認是IncludeDependents (也稱為子實體),但EF7的Add()行為並未將Venue識別為Show的子項。在OnModelCreating您需要指定VenueShow之間的關係。請參閱EF7文檔中的關係

例:

modelBuilder.Entity<Venue>(entityBuilder =>
{
    entityBuilder
        .HasMany(v => v.Shows)
        .WithOne(s => s.Venue)
        .HasForeignKey(s => s.VenueId);
});

即使這樣,你仍然需要在Venue的新實例上調用.Add,因為Show不是Venue的依賴(孩子)。

private static void AddShows(NettlesContext db)
{
    var fulton = new Venue()
            {
                Name = "Fulton Community Center",
            };
    var club = new Venue()
            {
                Name = "Milwaukie Community Club",
            };
    db.Venues.Add(fulton);
    db.Venues.Add(club);

    var shows = new List<Show>()
    {
        new Show()
        {
            Title = "Portland Country Dance Community Contra Dance",
            Venue = fulton,
        },
        new Show()
        {
            Title = "Portland Roadhouse Contra Dance",
            Venue = club
        },
    };
    context.Shows.AddRange(shows);
}

值得注意的是:.Add()的這種行為一直是EF7 RC1混亂的根源,它的行為可能在EF7 RC2中發生了變化。請參閱https://github.com/aspnet/EntityFramework/pull/4132


熱門答案

您需要更新模型

public class Venue
{
  public int Id { get; set; }
  public string Name {get; set; }
  //...
  public List<Show> Shows { get; set; }
 }
public class Show
{
  public int Id { get; set; }
  public int VenueId { get; set; }
  [ForeignKey("VenueId")]
  public Venue Venue { get; set; }
  //...
}

ForegnKey屬性用於定義兩個表之間關係的foriegn鍵



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因