Entity FrameWork 单表对多实体

一个影片信息Clips表,四个字段:clipId,clipName,fileSize,fileName

 

方案一:

    [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的。

方案二:

 

[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我是没有找到解决方案。

还有就是构造函数一定不要去new附属实体类,会进入死循环。

 

方案三:使用TPH(Table per Hierarchy)

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值不相同。

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。

但是这种方案多实体其实就导致数据虽然在一个表,但是内容无法在三个类中共享了,失去了原有的设计初衷。

 

你可能感兴趣的:(framework)