识别关系的外键映射

时间:2015-07-07 07:47:46

标签: c# entity-framework ef-code-first ef-fluent-api

我面临以下问题的foriegn密钥关联问题。

例如,有三个实体,即一,二和三。两个依赖于One,就像Three依赖于Two。

另外两个人将会有三个人和一个人可能会有两个人(一对多人)

由于Two和Three依赖于One和Two,我使用识别关系。但是,当外键映射我得到以下异常时..

  

Two_Three_Source_Two_Three_Target :::中的属性数量   关系约束中的依赖和主要角色必须是   相同

public class Profile
{
    [System.Xml.Serialization.XmlElement("LibId")]
    public string LibId { get; set; }

    [System.Xml.Serialization.XmlElement("ProfileId")]
    public string ProfileId { get; set; }
}



[System.Xml.Serialization.XmlRoot("ProfileCollection")]
public class ProfileCollection
{
    [XmlArray("Profiles")]
    [XmlArrayItem("Profile", typeof(Profile))]
    public Profile[] Profile { get; set; }
}

public class XMLFile
{
    public String LibId;
    public String ProfileId;
}

public static String ReadXML(String libID)
{

    var foo = "";
    var xml = XDocument.Load(@"C:\Projects\OneSearch\XML\Profiles.xml");

    foo = (from n in xml.Descendants("Profiles")
           where n.Element("Profile").Attribute("LibId").Value  == libraryID
           select n.Element("Profile").Attribute("ProfileId").Value).FirstOrDefault();

我想通过Fluent Mapping

帮助解决这个问题

修改

我选择这个apprach(识别关系)的原因是使下面的行工作(从db中删除子记录)

public class One
    {
    public long Id{get;set;}
    public ICollection<Two> TwoList{get;set;}
    }


 public class Two
    {
    public long Id{get;set;}
    public long OneId{ get; set; }
    public ICollection<Three> ThreeList{get;set;}
    }


 public class Three
    {
    public long Id{get;set;}
    public long TwoId{ get; set; }
    }


public class OneMap: BaseEntityMap<One>
    {
        public OneMap()
        {
        this.HasKey(t => t.Id);
         HasMany(t => t.Two).WithRequired().HasForeignKey(t =>  t.OneId);
         ToTable("One");
        }
    }

 public class TwoMap : BaseEntityMap<Two>
    {
        public TwoMap ()
        {
            this.HasKey(t => new { t.Id, t.OneId});
            ToTable("Two");
            HasMany(t => t.ThreeList).WithRequired().HasForeignKey(t => t.TwoId);
        }
    }

public class ThreeMap : BaseEntityMap<Three>
    {
        public ThreeMap ()
        {
            HasKey(t => new { t.Id, t.TwoId});
            ToTable("Three");
        }
    }

1 个答案:

答案 0 :(得分:1)

遵循模型并不简单:)无论如何,问题在于三。三个需要引用两个。 Two的主键是One.Id和Id(Two.Id)。另一个问题可能是Id of Three(我认为它应该是Id,TwoId,OneId,但可能没有必要让EF工作)。

这里有一个例子。

public class Model9Context : DbContext
{
    public Model9Context(DbConnection connection)
        : base(connection, false)
    { }

    public DbSet<One> Ones { get; set; }
    public DbSet<Two> Twos { get; set; }
    public DbSet<Three> Threes { get; set; }

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

        modelBuilder.Configurations.Add(new OneMap());
        modelBuilder.Configurations.Add(new TwoMap());
        modelBuilder.Configurations.Add(new ThreeMap());
    }
}


public class One
{
    public int Id { get; set; }
    public ICollection<Two> TwoList { get; set; }
}


public class Two
{
    public int Id { get; set; }
    public int OneId { get; set; } 
    public virtual One One { get; set; }
    public virtual ICollection<Three> ThreeList { get; set; }
}


public class Three
{
    public int Id { get; set; }
    public int TwoId { get; set; }
    public int OneId { get; set; }
    public virtual Two Two { get; set; }
}


public class OneMap : EntityTypeConfiguration<One>
{
    public OneMap()
    {
        this.HasKey(t => t.Id);
        ToTable("One");
    }
}

public class TwoMap : EntityTypeConfiguration<Two>
{
    public TwoMap()
    {
        this.HasKey(t => new { t.Id, t.OneId });
        ToTable("Two");

        HasRequired(t => t.One).WithMany(t => t.TwoList).HasForeignKey(t => t.OneId);
    }
}

public class ThreeMap : EntityTypeConfiguration<Three>
{
    public ThreeMap()
    {
        HasKey(t => new { t.Id, t.OneId, t.TwoId });
        ToTable("Three");

        HasRequired(t => t.Two).WithMany(t => t.ThreeList).HasForeignKey(t => new {t.OneId, t.TwoId});
    }
}

这是EF在DBMS中定义的外键

ALTER TABLE [Three] ADD CONSTRAINT [FK_Three_Two_OneId_TwoId] FOREIGN KEY ([OneId], [TwoId]) REFERENCES [Two] ([Id], [OneId])

修改
为了完整性,使用此映射,One的Id字段由EF生成为自动增量,而两个和三个字段Id不生成为自动增量。