实体框架代码首先是多对多关系不起作用

时间:2015-08-12 23:14:51

标签: c# entity-framework

我们首先使用实体​​框架6代码来存储一个复杂的对象树,如下所示:

public abstract class DataCode
{
    public long Id { get; set; }
    public string Code { get; set; }
    public string Description { get; set; }
    public bool IsActive { get; set; }
}

public class InternCode : DataCode
{
    public string PrimaryRelationalOperator { get; set; }
    public string PrimaryValue { get; set; }
    public string SecondaryRelationalOperator { get; set; }
    public string SecondaryValue { get; set; }
}

public class Model : DataCode
{
    public ICollection<string> Aliases { get; set; }
    public bool ExportOnly { get; set; }
    public void GetOptions()
    {
        throw new NotImplementedException();
    }
}

public class Version
{
    public long Id { get; set; }
    public string Description { get; set; }
    public string Status { get; set; }
    public float VersionNumber { get; set; }
    public virtual PriceLevel PriceLevel { get; set; }
    public DateTime EffectiveDate { get; set; }
    public virtual ICollection<Model> Models { get; set; }
    public virtual ICollection<InternCode> DataReleaseLevels { get; set; }
}

因此,Version可以引用许多Model,每个DataCode都是Version。但是另一个Model可以引用同一组virtual s(因此PriceLevel关键字,我认为就是你这样做的方式)。 DataCode也是VersionInternCode也可以包含多个DataCode个,每个DataCode,但这是另一个故事。无论如何,EF生成的var ModelList = new List<Model> { new Model { Code = "001-230", Description = "Model 230" }, new Model { Code = "001-231", Description = "Model 231" }, new Model { Code = "001-232", Description = "Model 232" }, new Model { Code = "001-233", Description = "Model 233" }, // and many more } var versions = new List<Entities.Version> { new Entities.Version { VersionNumber=2.1F, Description = "Version 2.1 for Model Group A", EffectiveDate = DateTime.Parse("1/15/1995"), Models=new List<Model> { ModelList.Find( m => m.Code == "001-230"), ModelList.Find( m => m.Code == "001-231"), ModelList.Find( m => m.Code == "001-232"), ModelList.Find( m => m.Code == "001-233"), }, Status = "Draft" }, new Entities.Version { VersionNumber=2.2F, Description = "Version 2.2 for Model Group A", EffectiveDate = DateTime.Parse("7/15/1995"), Models=new List<Model> { ModelList.Find( m => m.Code == "001-230"), ModelList.Find( m => m.Code == "001-231"), ModelList.Find( m => m.Code == "001-232"), ModelList.Find( m => m.Code == "001-233"), }, Status = "Draft" }, new Entities.Version { VersionNumber=2.3F, Description = "Version 2.3 for Model Group A", EffectiveDate = DateTime.Parse("1/15/1996"), Models=new List<Model> { ModelList.Find( m => m.Code == "001-230"), ModelList.Find( m => m.Code == "001-231"), ModelList.Find( m => m.Code == "001-232"), ModelList.Find( m => m.Code == "001-233"), }, Status = "Draft" } }; 表格中有很多内容。

我们有以下 DataInitializer 代码:

Version_VersionId

保存更改,牺牲鸡和其他所有内容后,我们发现数据库中的 DataCode 表创建了两个名为Version_VersionId1和{{{ 1}}。第一个具有空值,第二个具有创建的最后Id记录的Version。至少,我希望它会为Version_VersionId成员的每个Version创建一个新的Model列。这对我来说似乎非常低效,但至少它会起作用。相反,数据似乎是在先前的Version引用上踩踏。

我希望我们能用FluentAPI解决这个问题,但我不知道如何解决这个问题。有没有人有建议?

1 个答案:

答案 0 :(得分:1)

在开始之前,解决问题之后,还要关注public ICollection<string> Aliases { get; set; },因为无法以这种方式进行映射。

背景非常重要。对我来说很奇怪你有一个DataCode表(DataCode类是抽象的,所以你 - 和EF - 不能创建它)。 无论如何,使用这个上下文

public class TestContext : DbContext
{
    public TestContext(DbConnection connection) : base(connection, true) { }

    public DbSet<InternCode> InternCodes { get; set; }
    public DbSet<Model> Models { get; set; }
    public DbSet<Version> Versions { get; set; }


}

按预期创建三个表。 InternCode有一个Version_Id,Model有一个Version_Id,因为你没有在Model和InternCode上指定任何关于版本的东西,所以EF假设一个InternCode(和一个Model)只有一个版本

要实现单个Model(和单个InternCode)可以与多个版本相关,您可以执行以下操作:

public class TestContext : DbContext
{
    public TestContext(DbConnection connection) : base(connection, true) { }

    public DbSet<InternCode> InternCodes { get; set; }
    public DbSet<Model> Models { get; set; }
    public DbSet<Version> Versions { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new VersionMap());
    }
}

public class InternCode : DataCode
{
    public string PrimaryRelationalOperator { get; set; }
    public string PrimaryValue { get; set; }
    public string SecondaryRelationalOperator { get; set; }
    public string SecondaryValue { get; set; }

    public virtual ICollection<Version> Versions { get; set; }
}

public class Model : DataCode
{
    public ICollection<string> Aliases { get; set; }
    public bool ExportOnly { get; set; }
    public virtual ICollection<Version> Versions { get; set; }
    public void GetOptions()
    {
        throw new NotImplementedException();
    }
}


public class VersionMap : EntityTypeConfiguration<Version>
{
    public VersionMap()
    {
        // Relationships
        HasMany(t => t.Models)
            .WithMany(t => t.Versions);

        HasMany(t => t.DataReleaseLevels)
            .WithMany(t => t.Versions);
    }
}

在这种情况下,您将看到创建了几个表(表示n到m关系的表)