[英]Difficulty Concerning EF Code First Fluent API, TPH, and Foreign Keys
[英]Defining foreign key in EF 4.3.1 Code first using TPH
我创建了三个不同的类和一个用于存储不同类型地址的基类。 基类是与用户(已附加当前地址的用户)和邮政相关的邮政地址,其中包含有关邮政编码和城市的信息。
public class PostalAddress
{
public virtual User User { get; set; }
public DateTime LastUsed { get; private set; }
public string OrientationNumber { get; set; }
public int UserId { get; set; }
public int PostId { get; set; }
public int Id { get; set; }
public virtual Post Post { get; private set; }
public string Street { get; set; }
}
public class Post
{
public Post()
{
InvoicingAddresses = new List<InvoicingAddress>();
ShippingAddresses = new List<ShippingAddress>();
UserAddresses = new List<UserAddress>();
}
public virtual City City { get; set; }
public virtual ICollection<InvoicingAddress> InvoicingAddresses { get; private set; }
public virtual ICollection<ShippingAddress> ShippingAddresses { get; private set; }
public virtual ICollection<UserAddress> UserAddresses { get; private set; }
public int CityId { get; set; }
public int Id { get; set; }
public string ZipCode { get; set; }
}
使用类PostalAddressMap映射了PostalAddress类
public class PostalAddressMap : EntityTypeConfiguration<PostalAddress>
{
public PostalAddressMap()
{
// Primary Key
HasKey(t => t.Id);
// Properties
// Table & Column Mappings
ToTable("PostalAddress");
Property(t => t.Id).HasColumnName("Id");
Property(t => t.LastUsed).HasColumnName("LastUsed").HasColumnType("datetime2");
Property(t => t.OrientationNumber).HasColumnName("OrientationNumber");
Property(t => t.UserId).HasColumnName("UserId");
Property(t => t.PostId).HasColumnName("PostId");
Property(t => t.Street).HasColumnName("Street");
// Relationships
HasRequired(t => t.Post).WithMany(t => t.InvoicingAddresses).HasForeignKey(d => d.PostId);
HasRequired(t => t.User)
.WithMany(t => t.UserAddressess)
.HasForeignKey(d => d.UserId);
}
}
类InvoicingAddress,ShippingAddress和UserAddress从的PostalAddress类继承使用每个层级表的方法。 如果我想使用行设置关系
HasRequired(t => t.Post).WithMany(t => t.InvoicingAddresses).HasForeignKey(d => d.PostId);
我收到编译器错误无法将类型'System.Collections.Generic.ICollection <InvoicingAddress>'隐式转换为'System.Collections.Generic.ICollection <PostalAddress>'。 存在显式转换(您是否缺少演员表?)
拜托,您能帮我怎样在PostalAddress子类和其他TPT类型之间设置外键?
感谢您提供任何有用的答案。
您必须将PostId
和Post
属性从基类PostalAddress
移到派生类InvoicingAddress
等。
public class InvoicingAddress : PostalAddress
{
//...
public int PostId { get; set; }
public virtual Post Post { get; private set; }
}
...然后对派生类使用映射:
public class InvoicingAddressMap : EntityTypeConfiguration<InvoicingAddress>
{
public InvoicingAddressMap()
{
HasRequired(t => t.Post)
.WithMany(t => t.InvoicingAddresses)
.HasForeignKey(d => d.PostId);
}
}
或者,您必须在Post
使用单个集合作为基类:
public virtual ICollection<PostalAddress> Addresses { get; private set; }
然后,您可以使用原始映射。
后一种方法的缺点是,当您使用PostalAddress
加载或延迟加载时,所有PostalAddress
都将被加载,并且您无法控制要加载的地址类型。 地址加载后,您可以通过内存中的类型进行过滤:
var invoicingAddresses = post.Addresses.OfType<InvoicingAddress>();
通过显式加载,您还可以过滤:
var post = context.Posts.Single(p => p.Id == 1);
context.Entry(post).Collection(p => p.Addresses).Query()
.OfType<InvoicingAddress>().Load();
...这将仅使用InvoicingAddress
填充Addresses
集合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.