一個影片信息Clips表,四個字段:clipId,clipName,fileSize,fileName函數
方案一:ui
[Table("Clips")] public class Clip { public Clip() { File = new ClipFile(); } [Key] [Column("clipId")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Column("clipName")] public string Name { get; set; } public ClipFile File { get; set; } } [ComplexType] public class ClipFile { [Column("fileSize")] public string Size { get; set; } [Column("fileName")] public string Name { get; set; } }
缺點:ClipFile不會延遲加載,不管你ClipFile申明是否爲virtual的。spa
方案二:設計
[Table("Clips")] public class Clip { [Key] [Column("clipId")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [ForeignKey("FileOf")] public int Id { get; set; } [Column("clipName")] public string Name { get; set; } //[Required] public virtual ClipFile FileOf { get; set; } } [Table("Clips")] public class ClipFile { [Key] [Column("clipId")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [ForeignKey("ClipOf")] public int Id { get; set; } [Column("fileSize")] public string Size { get; set; } [Column("fileName")] public string Name { get; set; } //[Required] public virtual Clip ClipOf { get; set; } }
這種方案也存在問題,不Include調用關聯virtual實體類,永遠是null,不支持延遲加載,非常鬱悶。SqlServer聽說能夠解決,MySql我是沒有找到解決方案。code
還有就是構造函數必定不要去new附屬實體類,會進入死循環。對象
方案三:使用TPH(Table per Hierarchy)blog
public abstract class ClipBase { [Key] [Column("clipId")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Column("clipName")] public string Name { get; set; } } public class ClipFile : ClipBase { [Column("fileName")] public string FileName { get; set; } } public class ClipSize : ClipBase { [Column("fileSize")] public int Size { get; set; } }
並且必須是用Fluent API進行配置,還必須爲Clips添加字段Discriminator(字段名稱和類型均可以根據本身須要進行修改),這個字段的值用於區分是哪一個類的數據,因此務必保證每一個派生類的HasValue值不相同。ip
modelBuilder.Entity<ClipBase>().Map(m=> { m.ToTable("Clips"); //m.Requires("Discriminator").HasValue("0"); //若是ClipBase不申明爲抽象類這須要用此加以區分 }) .Map<ClipFile>(m => m.Requires("Discriminator").HasValue("1")) .Map<ClipSize>(m => m.Requires("Discriminator").HasValue("2"));
建立對象能夠用基類的DbSet進行添加,也能夠用派生類本身的DbSet進行添加。選取的時候你能夠基類的DbSet.OfType<ClipFile>(),也能夠用派生類本身的DbSet。get
可是這種方案多實體其實就致使數據雖然在一個表,可是內容沒法在三個類中共享了,失去了原有的設計初衷。string