【问题标题】:Entity Framework 6.x Code First PRIMARY KEY constraint error saving Many to Many fieldEntity Framework 6.x Code First PRIMARY KEY约束错误保存多对多字段
【发布时间】:2018-09-19 21:52:24
【问题描述】:

我正在使用 Code First,我正在尝试添加 2 条共享相同(构面)对象的记录。 EF 试图两次添加相同的共享对象,所以我得到了Violation of PRIMARY KEY constraint 错误。考虑一下..

XML

<RecipeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <Recipes>
        <Recipe author="Mr. Cook" createdDate="08/30/2018" description="Cheesesteak with mushrooms" name="Mushroom Cheesesteak" recipe_id="13">
            <Facet Taxonomy_id="1" name="Lunch" />
            <Facet Taxonomy_id="1" name="Dinner" />
            <Facet Taxonomy_id="2" name="American" />
        </Recipe>
        <Recipe author="Jane Doe" createdDate="10/01/2018" description="Vegan Hotdog" name="Vegan Hotdog" recipe_id="9">
            <Facet Taxonomy_id="1" name="Snack" />
            <Facet Taxonomy_id="1" name="Lunch" />  <!-- This is breaking EF! -->
            <Facet Taxonomy_id="2" name="Vegetarian" />
        </Recipe>
    </Recipes>
</RecipeSet>

Recipe 和 Facets 具有多对多关系。

public class Recipe
{
    [Key]
    public int Recipe_id { get; set; }  
    public string Author { get; set; }
    public DateTime CreatedDate { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Facet> Facets { get; set; }
}

//Facet needs to have a unique taxonomy id and name combination
public class Facet
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Facet_id { get; set; }

    [Key]
    [Column(Order = 0)]
    public int Taxonomy_id { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(500)]
    public string Name { get; set; }

    public virtual ICollection<Recipe> Recipes { get; set; }
}

public class RecipeContext : DbContext
{
    public RecipeContext() : base("name=RecipeContextConn")
    {
        Database.SetInitializer<RecipeContext>(new CreateDatabaseIfNotExists<RecipeContext>());
    }

    public DbSet<Recipe> Recipe { get; set; }
    public DbSet<Facet> Facet { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

// Automapper configuration
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<RecipeElement, Recipe>()
        .ForMember(dest => dest.Facets, opt => opt.MapFrom(src => src.Facet));

    cfg.CreateMap<FacetElement, Facet>();
});

Mapper = config.CreateMapper();

在 Foreach 循环后保存时,我的代码中断了。

foreach (var recipeElement in fullRecipeSet.Recipes.Recipe)
{
    // Using Automapper to map from one object to another
    Recipe recipeDto = Mapper.Map<Recipe>(recipeElement);

    ctx.Recipe.Add(recipeDto);
}

ctx.SaveChanges();

我如何告诉 EF 只保存唯一的 Facet 一次?

【问题讨论】:

    标签: c# entity-framework-6 many-to-many automapper


    【解决方案1】:

    我在这里找到了一些建议Entity Framework 6 inserting duplicate values

    我必须先将独特的方面保存在数据库中。然后,当我将 xml 映射到配方时,删除映射的构面并从数据库中分配创建的构面。这可确保所有配方共享相同的确切 facet 对象

    Recipe recipeDto = MapInitializer.Mapper.Map<Recipe>(recipeElement);
    
    var facs = recipeDto.Facets;
    
    // Null out the facets that gets mapped from the xml. 
    recipeDto.Facets = new List<Facet>();
    
    // Reassign facet from the db. Otherwise, trying to save the recipe with the 
    // facets that was mapped from the xml will cause duplicate facts trying to insert.
    foreach (var f in facs)
    {
        var dbFacet = ctx.Facet.Where(x => x.Taxonomy_id == f.Taxonomy_id && x.Name == f.Name).First();
        recipeDto.Facets.Add(dbFacet);
    }
    
    ctx.Recipe.Add(recipeDto);
    

    【讨论】:

    • 几年后来到这里,但谢谢。这救了我。我在保存许多重复的孩子时遇到了问题。谢谢!!
    猜你喜欢
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 2011-04-06
    • 2015-06-07
    • 2014-07-22
    • 2013-01-12
    相关资源
    最近更新 更多