【问题标题】:Entity Framework many to many - Code First - Migrations实体框架多对多 - 代码优先 - 迁移
【发布时间】:2015-07-13 22:04:29
【问题描述】:

我有产品类:

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Language> Languages { get; set; }
}

语言类:

public class Language
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }

}

在我的 EntityTypeConfiguration 中:

public class ProductMap : EntityTypeConfiguration<Product>
{

    public ProductMap()
    {
        HasKey(m => m.Id);
        Property(p => p.Name).IsRequired();

       HasMany(p => p.Languages)
            .WithMany(l => l.Products)
            .Map(x => x.ToTable("ProducLanguages")
                .MapLeftKey("ProductId")
                .MapRightKey("LanguageId"));

        //Table  
        ToTable("Products");
    }
}

这会按预期创建第三个表,但是当我使用以下种子执行更新数据库时:

protected override void Seed(EcoomerceContext context)
    {
        var languages = new List<Language>
        {
            new Language {Name = "Portuguese"},
            new Language {Name = "English"},
            new Language {Name = "Spanish"}
        };

        var languagePt = new List<Language>
        {
            new Language {Name = "Portuguese"},
        };

        //languages.ForEach(a => context.Languages.Add(a));

        new List<Product>
        {
          new Product {Name = "NameProduct1", Languages = languages},
          new Product {Name = NameProduct2 , Languages = languagePt},
        }.ForEach(a => context.Products.Add(a));

        context.SaveChanges();
    }

它像这样更新关系表 ProducLanguages:

它正在插入一种不存在的语言(数字 4),我期望的结果是:

我做错了什么?

提前致谢。

【问题讨论】:

    标签: c# .net entity-framework ef-code-first migration


    【解决方案1】:

    你需要指定每个实体的Id,即使PK是Identity。指定将在数据库中使用的Id 至关重要,否则每个Update-Database 都会创建新记录。

    您还应该使用 AddOrUpdate 扩展方法,该方法是为在迁移期间播种数据而创建的。在此方法中,您可以指定一个表达式来了解应该使用什么属性来检查是否有必要执行 Add 或 @ 987654327@ 操作,但如果您未在实体中指定Id,则会添加一个新行并保留旧行。所以最后,你的Seed 方法可能是这样的:

     protected override void Seed(ConsoleApplication3.YourContext context)
     {
            var languages = new[]
            {
                new Language {Id = 1, Name = "Portuguese"},
                new Language {Id = 2, Name = "English"},
                new Language {Id = 3, Name = "Spanish"},
                new Language {Id = 4, Name = "French"},
            };
    
            // This way you can add all the languages even when there is not associated to a product
            // The first parameter is an expression to know what properties should be used when determining whether an Add or Update operation should be performed
            context.Languages.AddOrUpdate(l => l.Name, languages);
    
            var products = new[]
            {
                new Product {Id = 1, Name = "NameProduct1", Languages = new List<Language> {languages[0],languages[1],languages[3]}},
                new Product {Id = 2, Name = "NameProduct2", Languages = new List<Language> {languages[0]}},
            };
            context.Products.AddOrUpdate(p=>p.Name,products);
    
            context.SaveChanges();
    }
    

    【讨论】:

    • 我做了你的改变,得到了同样的结果。
    猜你喜欢
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    相关资源
    最近更新 更多