Entity FrameWork 單表對多實體

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

相關文章
相關標籤/搜索