16

我正在使用 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',因为它们不在同一类型层次结构中,或者它们之间没有有效的一对一外键关系和匹配的主键。

我究竟做错了什么?

4

6 回答 6

8

似乎问题在于这种关系被解释为一对0..1而不是一对一。

Review 端的外键int PictureInfoId是不需要/忽略的,因此它的不可为空性并没有使关系的 Review 端成为必需的。删除这个不需要的键并将 [Required] 属性添加到 PictureInfo 导航属性解决了它。

这是更正后的 Review 课程。

[Table("Review")]
public class Review
{
    public int Id { get; set; }
    [Required]
    public PictureInfo PictureInfo { get; set; }
}
于 2014-06-28T10:50:35.550 回答
7

我已经设法通过 fluent 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 关系绑定,然后将它们映射到同一个表。

于 2014-06-27T20:19:45.347 回答
1

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

于 2015-11-27T20:39:46.293 回答
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; }
}
于 2016-05-06T23:53:45.173 回答
0
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; }
    } 
}
于 2016-12-09T17:43:19.680 回答
-2

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

[Table("Review")] 公共类评论 { ... }

[Table("Review")] 公共类PictureInfo { ... }

为了

[Table("Review")] 公共类评论 { ... }

[Table(" PictureInfo ")] 公共类PictureInfo { ... }

于 2015-09-16T14:09:44.267 回答