EF Db First方法-处理不带PK的表

时间:2019-01-02 17:30:19

标签: c# .net-core entity-framework-core

我尝试使用db first方法为现有db创建上下文,并得到以下错误:

  

//无法为表'dbo.TT_ProjectMembers'生成实体类型。   请查看警告消息。无法识别主键   表'dbo.TT_ProjectMembers'。无法为生成实体类型   表'dbo.TT_ProjectMembers'。

TT_ProjectMembers表包含两列:ProjectId(int)UserId(int)。不幸的是,我没有机会 数据库更新(添加新列等)。

我决定手动创建实体和所有其他内容。我决定 为此表设置复合键,因为这样做很有意义-同一行有2行是错误的 ProjectId和UserId。

//entity class

    public class ProjectMember
    {
        public int ProjectID { get; set; }
        public int UserID { get; set; }

    }

    //dbcontext property
    public virtual DbSet<ProjectMember> ProjectMembers { get; set; }    

    // entity config
        modelBuilder.Entity<ProjectMember>(entity =>
    {
        entity.ToTable("TT_ProjectMembers");
        entity.HasKey(p => new {p.ProjectID, p.UserID});
    });

令人惊讶的是,它奏效了。现在我可以执行任何CRUD操作,但是我有一些问题:

  1. 这样解决问题是否存在任何不利条件或问题?您通常如何解决此问题?
  2. 为什么EF需要您在桌上摆放PK?
  3. EF如何在幕后工作? (我知道这是一个广泛的问题,因此,对任何书籍/文章的建议都将不胜感激)

1 个答案:

答案 0 :(得分:4)

1)这样。将M:M关系分解为两个1:M的中间人表应将两个外键列作为其PK。使此类表具有第三个PK列是一个菜鸟错误

2)因为这就是您查询相关数据时的查找方式(employee.Company.Name可能会为该员工加载公司数据,因此可能会产生类似SELECT Company.* FROM Company JOIN Employee ON Company.ID = Employe.CompanyId WHERE Employee.Id = @id的信息,或者如果加入不使用,请从该员工查询CompanyId,然后从Company ID查询公司详细信息),以及如何确定在持久更改时仅在行上进行更新。 “没有PK,没有比赛!”

3)恐怕SO太宽泛,但是您急于寻找一些资源,这些资源向您展示如何激活其生成的查询的日志记录,然后您可以看到context.Employee.Where(e => e.Name = "John")它变成SELECT x FROM Employee WHERE name = 'John'