即使定义了其他主键,实体框架 6 也会创建 Id 列

Emi*_*org 5 c# entity-framework data-annotations entity-framework-6 ef-fluent-api

我将 DataObject 定义为:

public class SensorType : EntityData
{
    //PKs
    public string CompanyId { get; set; }
    public string ServiceId { get; set; }

    public string Type { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并使用 fluent API 使 CompanyId 和 ServiceId 成为复合键:

modelBuilder.Entity<SensorType>()
            .HasKey(t => new { t.CompanyId, t.ServiceId });

//No autogeneration of PKs
modelBuilder.Entity<SensorType>().Property(t => t.ServiceId)
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
modelBuilder.Entity<SensorType>().Property(t => t.CompanyId)
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
Run Code Online (Sandbox Code Playgroud)

即使设置了主键,实体框架也会在我运行 Add-Migration 时创建一个名为 Id 的列:

CreateTable(
            "dbo.SensorTypes",
            c => new
                {
                    CompanyId = c.String(nullable: false, maxLength: 128),
                    ServiceId = c.String(nullable: false, maxLength: 128),
                    Type = c.String(),
                    Id = c.String(
                        annotations: new Dictionary<string, AnnotationValues>
                        {
                            { 
                                "ServiceTableColumn",
                                new AnnotationValues(oldValue: null, newValue: "Id")

                   ...
                })
            .PrimaryKey(t => new { t.CompanyId, t.ServiceId })
            .Index(t => t.CreatedAt, clustered: true);

    }
Run Code Online (Sandbox Code Playgroud)

如何防止 EF 添加此列?

Joh*_*oon 3

EntityData我怀疑这与您派生类并EntityData具有名为 的属性这一事实有关Id。我的猜测是 EF 变得混乱,因为有一个属性遵循它的键命名约定(即Id)和显式定义的键。

我怀疑你必须告诉它明确忽略Id.

MSDN:实体数据类

更新:

我假设您正在使用 Azure 来实现此目的。这个问题的答案中有一些附加信息,可以帮助您找到最佳解决方案。

不过,我同意@Basic 对你的问题的评论。由于复合键引入的复杂性(以及其他问题),我通常回避使用 EF 的复合键。CompanyId我怀疑对您的和字段的独特约束ServiceId将实现您想要的效果,而无需将它们包含在 的主键中SensorType。这也意味着您可以仅使用派生Id属性作为主键,从而避免整个问题。我不知道这对于您的实施是否可行,但这是值得考虑的事情。