我已经制作了模拟我所拥有的类的简单类(抱歉我必须编写类,通常的示例数据库没有我想要询问的结构):
public class Animal
{
public System.Guid ID { get; set; }
public string SpeciesName { get; set; }
public virtual ICollection<AnimalSpecies> AnimalSpecies { get; set; }
}
物种鱼:
public class Fish
{
public System.Guid ID { get; set; }
public int Freshwater { get; set; }
}
Spieces Reptile:
public class Reptile
{
public System.Guid ID { get; set; }
public int LifeExpectancy { get; set; }
}
AnimalSpecies类:
public class AnimalSpecies
{
public System.Guid Animal_ID { get; set; }
public System.Guid Species_ID { get; set; }
public virtual Animal Animal { get; set; }
}
动物种类的定位:
public AnimalSpeciesMap()
{
this.HasKey(t => new { t.Animal_ID, t.Spieces_ID });
this.Property(t => t.Animal_ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(t => t.Spieces_ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.ToTable("AnimalSpecies");
this.Property(t => t.Animal_ID).HasColumnName("Animal_ID");
this.Property(t => t.Spieces_ID).HasColumnName("Spieces_ID");
// Relationship between Animal and AnimalSpieces:
this.HasRequired(t => t.Animal)
.WithMany(t => t.AnimalSpecies)
.HasForeignKey(d => d.Animal_ID);
}
由于Spieces_ID没有外键,有没有办法映射AnimalSpecies和Fish / Reptile之间的关系?
答案 0 :(得分:3)
我认为不可能将AnimalSpecies.Species_ID
作为外键参与的映射定义为两个不同的关系 - 一个在AnimalSpecies
和Fish
之间,另一个在{{}之间。 1}}和AnimalSpecies
。
对我而言,您的模型似乎缺少Reptile
和Species
的{{1}}基类。如果您有这样的基类,您的模型可能如下所示:
Fish
映射:
Reptile
如果您的public class Animal
{
public System.Guid ID { get; set; }
//...
public virtual ICollection<AnimalSpecies> AnimalSpecies { get; set; }
}
public class Species // I think the base class could also be abstract
{
public System.Guid ID { get; set; }
//...
public virtual ICollection<AnimalSpecies> AnimalSpecies { get; set; }
}
public class Fish : Species
{
public int Freshwater { get; set; }
}
public class Reptile : Species
{
public int LifeExpectancy { get; set; }
}
public class AnimalSpecies
{
public System.Guid Animal_ID { get; set; }
public System.Guid Species_ID { get; set; }
public virtual Animal Animal { get; set; }
public virtual Species Species { get; set; }
}
类没有除键和导航属性之外的其他成员,您还可以从模型中删除此类,并在public AnimalSpeciesMap()
{
this.HasKey(t => new { t.Animal_ID, t.Spieces_ID });
this.Property(t => t.Animal_ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(t => t.Spieces_ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.ToTable("AnimalSpecies");
this.HasRequired(t => t.Animal)
.WithMany(t => t.AnimalSpecies)
.HasForeignKey(d => d.Animal_ID);
this.HasRequired(t => t.Species)
.WithMany(t => t.AnimalSpecies)
.HasForeignKey(d => d.Species_ID);
}
和{{之间映射直接的多对多关系1}}(从域观点来看没有意义,因为动物只属于一个物种,是吗?):
AnimalSpecies
映射:
Animal
Species
现在是一个隐藏表,由EF管理,用于多对多关系,而不会在模型中公开。
我不确定我是否理解你的问题。这就是我想到的。
修改强>
如果没有为派生类指定任何特殊映射,EF将假定TPH(Table-Per-Hierarchy)继承,这意味着所有子类与基类一起存储在同一个类中数据库表,由鉴别器列区分。
如果您有许多具有许多属性的派生类,那么更好的继承策略可能是TPT(Table-Per-Type)。在这种情况下,您可以在映射中为每个子类定义自己的表:
public class Animal
{
public System.Guid ID { get; set; }
//...
public virtual ICollection<Species> Species { get; set; }
}
public class Species // I think the base class could also be abstract
{
public System.Guid ID { get; set; }
//...
public virtual ICollection<Animal> Animals { get; set; }
}
public class Fish : Species
{
public int Freshwater { get; set; }
}
public class Reptile : Species
{
public int LifeExpectancy { get; set; }
}
// no AnimalSpecies class anymore
现在每个派生类都有自己的表,基类存储在表“Species”中。当您查询鱼时,EF将在数据库中创建适当的连接:
public AnimalMap()
{
this.HasMany(a => a.Species)
.WithMany(s => s.Animals)
.Map(x =>
{
x.MapLeftKey("Animal_ID");
x.MapRightKey("Species_ID");
x.ToTable("AnimalSpecies");
});
}
您可以在此处详细了解不同的继承映射策略及其优缺点: