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

本文关键字:关系 不起作用 框架 代码 实体 | 更新日期: 2023-09-27 18:07:30

我们使用实体框架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,每个CCD_2都是一个DataCode。但另一个Version可以引用同一组Models(因此使用了virtual关键字,我认为就是这样做的(。CCD_ 7也是CCD_。一个Version也可以有许多InternCode,每个都是一个CCD11,但那是另一回事。无论如何,EF生成的DataCode表中有很多内容。

我们有以下DataInitializer代码:

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

在保存了更改、牺牲了一只鸡和所有其他东西之后,我们发现数据库中的DataCode表正在创建名为Version_VersionIdVersion_VersionId1的两列。第一个具有空值,第二个具有创建的最后一个Version记录的Id。至少,我希望它会为Model所属的每个Version创建一个新的Version_VersionId列。这在我看来效率低下得可怕,但至少它能起作用。相反,这些数据似乎践踏了以前的Version参考文献。

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

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

在开始之前,在解决问题之后,还要注意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; }

}

按照预期创建了三个表。InternetCode有一个Version_Id,Model有一个Version _Id,因为您没有在Model和InternetCode上指定任何关于版本的内容,所以EF假设一个InternetCode(和一个Model(只有一个版本

为了实现单个模型(和单个InternetCode(可以与多个版本相关,您可以执行以下操作:

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关系的表(