一个影片信息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