简体   繁体   English

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

[英]EF Db First approach - dealing with tables without PK's

I tried to create a context for existing db using db first approach and got the error below: 我尝试使用db first方法为现有db创建上下文,并得到以下错误:

// Unable to generate entity type for table 'dbo.TT_ProjectMembers'. //无法为表'dbo.TT_ProjectMembers'生成实体类型。 Please see the warning messages. 请查看警告消息。 Unable to identify the primary key for table 'dbo.TT_ProjectMembers'. 无法识别表'dbo.TT_ProjectMembers'的主键。 Unable to generate entity type for table 'dbo.TT_ProjectMembers'. 无法为表“ dbo.TT_ProjectMembers”生成实体类型。

TT_ProjectMembers table contains two columns: ProjectId(int) UserId(int). TT_ProjectMembers表包含两列:ProjectId(int)UserId(int)。 Unfortunately, I have no opportunity of updating the database (adding new columns and so on). 不幸的是,我没有机会更新数据库(添加新列等)。

I decided to create the entity and all other stuff manually. 我决定手动创建实体和所有其他内容。 I decided to set up composite key for this table, because it just makes sense - it's wrong to have 2 rows with the same ProjectId and UserId. 我决定为此表设置复合键,因为这很有意义-两行具有相同的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});
    });

Surprisingly, it worked. 令人惊讶的是,它起作用了。 Now I can do any CRUD operations, but I have some questions: 现在我可以执行任何CRUD操作,但是我有一些问题:

  1. Is there any disadvantages or problems due to such solution of the problem? 这样解决问题是否有任何不利或问题? How do you usually solve this problem? 您通常如何解决此问题?
  2. Why EF needs you to have PK on the table? 为什么EF需要您在桌上摆放PK?
  3. How EF works under the hood? EF如何在幕后工作? (I know that this is a broad question, so any book/article advice will be appreciated) (我知道这是一个广泛的问题,因此,对任何书籍/文章的建议都将不胜感激)

1) Like this. 1)这样。 Middleman tables that decompose a M:M relationship into two 1:M should have the two foreign key columns as their PK. 将M:M关系分解为两个1:M的中间人表应将两个外键列作为其PK。 It's a rookie error to make such tables have a third PK column 使此类表具有第三个PK列是一个菜鸟错误

2) Because that's how it looks up related data when you ask for it ( employee.Company.Name might cause company data to be loaded for that employee, so perhaps results in something like SELECT Company.* FROM Company JOIN Employee ON Company.ID = Employe.CompanyId WHERE Employee.Id = @id or, if joins aren't used, querying the CompanyId from that employee, then querying the company details from the Company ID), and how it knows for sure it's updating only on row when persisting changes. 2)因为这就是当您要查询相关数据时它的查找方式( employee.Company.Name可能会导致为该雇员加载公司数据,因此可能会导致出现类似SELECT Company.* FROM Company JOIN Employee ON Company.ID = Employe.CompanyId WHERE Employee.Id = @id或者,如果不使用联接,则从该员工中查询CompanyId,然后从Company ID中查询公司详细信息),以及如何确定仅在行时更新持续的变化。 "No PK, no play!" “没有PK,没有比赛!”

3) Too broad for SO, i'm afraid, but feel fre to take a look for resources that show you how to activate logging of the queries it generates, then you can see when you do context.Employee.Where(e => e.Name = "John") how it becomes SELECT x FROM Employee WHERE name = 'John' etc 3)恐怕SO太宽泛,但是您不妨去寻找一些资源,这些资源向您展示如何激活它生成的查询的日志记录,然后您就可以看到何时执行context.Employee.Where(e => e.Name = "John")如何变成SELECT x FROM Employee WHERE name = 'John'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM