首页 文章

实体框架表拆分:不在同一类型层次结构中/没有有效的一对一外键关系

提问于
浏览
14

我正在使用Entity Framework 6和Code-First方法,我希望将两个实体放在同一个表中 . 我究竟做错了什么?

[Table("Review")]
public class Review
{
    public int Id { get; set; }
    public PictureInfo PictureInfo { get; set; }
    public int PictureInfoId { get; set; }
}

[Table("Review")]
public class PictureInfo
{
    [Key, ForeignKey("Review")]
    public int ReviewId { get; set; }
    public Review Review { get; set; }
}

我得到的错误:实体类型'PictureInfo'和'Review'不能共享表'Review',因为它们不在同一类型层次结构中,或者没有有效的一对一外键关系,它们之间具有匹配的主键 .

我究竟做错了什么?

6 回答

  • 0

    我已经成功地用流畅的api实现了你想要的东西 . Fluent api提供了比数据注释更丰富的配置选项 . 我改变了你的实体类:

    public class Review
    {
        public int Id { get; set; }
        public PictureInfo PictureInfo { get; set; }
    }
    

    不需要PictureInfoId属性,因为将在两个实体的主键上完成外键关系 .

    public class PictureInfo
    {
        public int Id { get; set; }
        public Review Review { get; set; }
    }
    

    由于Review和PictureInfo将映射到同一个表,因此需要共享相同的主键列,因此对于PictureInfo和Review,此列应具有相同的名称 . 如果您想保留名为ReviewId的PictureInfo主键属性,则可以执行此操作,但您需要将其名称映射到“Id” . 最后的DbContext:

    public class MyDbContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Review>().HasKey( e => e.Id );
            modelBuilder.Entity<Review>()
                .HasRequired(e => e.PictureInfo)
                .WithRequiredDependent(e => e.Review);
            modelBuilder.Entity<Review>().Map(m => m.ToTable("Review"));
            modelBuilder.Entity<PictureInfo>().Map(m => m.ToTable("Review"));
            modelBuilder.Entity<PictureInfo>().HasKey(e => e.Id);
    
            base.OnModelCreating(modelBuilder);
        }
    
        public DbSet<Review> Reviews { get; set; }
        public DbSet<PictureInfo> PictureInfos { get; set; }
    }
    

    OnModelCreating包含流畅的api映射定义 . 您所要做的就是在两个具有相同名称的实体上定义主键,将这两个实体绑定为1-1关系,然后将它们映射到同一个表 .

  • 5

    似乎问题是这种关系被解释为一对一,而不是一对一 .

    审阅结束时的外键 int PictureInfoId 不需要/被忽略,因此其不可空性不会使审阅结束所需的关系 . 删除此不需要的密钥并将[Required]属性添加到PictureInfo导航属性解决了它 .

    这是更正后的评论课 .

    [Table("Review")]
    public class Review
    {
        public int Id { get; set; }
        [Required]
        public PictureInfo PictureInfo { get; set; }
    }
    
  • 6

    解决此问题的另一种方法是创建仅包含所需字段的视图 . 然后将实体映射到视图 .

  • 1

    (这些测试和错误是针对EF 6.1.3编写的)

    第一次尝试

    [Table("Review")]
    public class Review
    {
        [Key]
        public int Id { get; set; }
        public PictureInfo PictureInfo { get; set; }
    }
    
    [Table("Review")]
    public class PictureInfo
    {
        [Key]
        public int Id { get; set; }
        public Review Review { get; set; }
    }
    

    有了上述实体,我收到了这个错误:

    无法确定类型之间关联的主要结束 . 必须使用关系流畅API或数据注释显式配置此关联的主要结尾 .

    第二次尝试

    [Table("Review")]
    public class Review
    {
        [Key]
        public int Id { get; set; }
    
        [Required]
        public PictureInfo PictureInfo { get; set; }
    }
    
    [Table("Review")]
    public class PictureInfo
    {
        [Key]
        public int Id { get; set; }
    
        [Required]
        public Review Review { get; set; }
    }
    

    实体类型'Review'和'PictureInfo'不能共享表'Review',因为它们不在同一类型层次结构中,或者没有有效的一对一外键关系,它们之间具有匹配的主键 .

    第三次尝试

    [Table("Review")]
    public class Review
    {
        [Key]
        public int Id { get; set; }
    
        [Required, ForeignKey("Id")]
        public PictureInfo PictureInfo { get; set; }
    }
    
    [Table("Review")]
    public class PictureInfo
    {
        [Key]
        public int Id { get; set; }
    
        [Required, ForeignKey("Id")]
        public Review Review { get; set; }
    }
    

    无法确定类型之间关联的主要结束 . 必须使用关系流畅API或数据注释显式配置此关联的主要结尾 .

    工作代码

    [Table("Review")]
    public class Review
    {
        [Key, ForeignKey("PictureInfo")]
        public int Id { get; set; }
    
        public PictureInfo PictureInfo { get; set; }
    }
    
    [Table("Review")]
    public class PictureInfo
    {
        [Key, ForeignKey("Review")]
        public int Id { get; set; }
    
        public Review Review { get; set; }
    }
    
  • -2
    using System.Linq;
    using System.Data.Entity;
    namespace Sample
    {
    

    class Program
        {
            static void Main(string[] args)
            {
                using (var context = new EmployeeDBContext())
                {
                    var result = context.Set<Employee>().Include(x => x.Department).ToArray();
                }
            }
        }
    

    public class EmployeeDBContext : DbContext
        {
            public EmployeeDBContext() : base("EmployeeDB") { }
    
            public DbSet<Employee> Employee { get; set; }
            public DbSet<Department> Department { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Department>().ToTable("Departments").HasKey(x => x.DepartmentId);
                modelBuilder.Entity<Employee>().ToTable("Employees").HasKey(x => x.Id);
                //ForeignKey mapping 
                modelBuilder.Entity<Employee>().HasRequired(x => x.Department).WithMany().HasForeignKey(x => x.DepartmentId);
                base.OnModelCreating(modelBuilder);
            }
        }
    

    //Domain Entity
        public class Employee
        {
            public int Id { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public Department Department { get; set; }
            public int DepartmentId { get; set; }
        }
    
        //Domain Entity
        public class Department
        {
            public int DepartmentId { get; set; }
            public string DepartmentName { get; set; }
        } 
    }
    
  • 0

    导致该错误的原因是表的定义在表“PictureInfo”的指令中重复 . 您只需要编辑该指令 .

    [表(“评论”)]公共课评论 [表(“评论”)]公共类PictureInfo

    对于

    [表(“评论”)]公共课评论 [表(“PictureInfo”)]公共类PictureInfo

相关问题