【问题标题】:How to set a Property of a subclass as the primary key using fluent API如何使用 fluent API 将子类的属性设置为主键
【发布时间】:2015-08-06 16:04:41
【问题描述】:

这是我的模型

  public class RepoDocument
  {
    public DocumentRecord Document { get; set; }

    public string Title { get; set; }

    public string Path { get; set; }
  }

这是子类定义:

public class DocumentRecord
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    // ... Other fields here...
}

我需要什么

我想让Id 作为RepoDocument 模型的主键。

我在我的数据库上下文中使用此代码:

  public class DocumentsContext : DbContext
  {
    public DocumentsContext()
        : base("name=DbConnectionString")
    {

    }
    public DbSet<RepoDocument> DocumentsTable { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<RepoDocument>().HasKey<Guid>(c => c.Document.Id);
    }
  }

问题

但是,当我在包管理器控制台中运行 add-migration 时,我收到以下错误:

属性表达式“c => c.Document.Id”无效。该表达式应表示一个属性:C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'。指定多个属性时使用匿名类型:C#: 't => new { t.MyProperty1, t.MyProperty2 }' VB.Net: 'Function(t) New With { t.MyProperty1, t.MyProperty2 }'。

问题

如何使用fluent API将我的模型子类的属性设置为数据库的主键?

【问题讨论】:

  • 这不是你定义子类的方式。正如您所定义的,RepoDocument 具有 DocumentRecord。如果您的意思是 RepoDocument 是 DocumentRecord,则不应将 DocumentRecord 声明为成员,而应将 DocumentRecord 作为超类包含在您的 RepoDocument 声明中:public class RepoDocument : DocumentRecord
  • @JerryFederspiel 我认为这只是一个无效的命名。子类作为在另一个内部使用的类:)
  • 是的,子类是指一个类作为另一个类的属性。
  • @AliSharabiani,不过,您不应该以不正确的方式使用术语。 Subclass 是继承关系的稳定命名,不是聚合。

标签: c# entity-framework ef-fluent-api


【解决方案1】:

您的问题不正确。您应该使用继承。

public abstract class RepoDocument
{
    public Guid Id { get; set; }

    public string Title { get; set; }

    public string Path { get; set; }
}

public class Document : RepoDocument
{

    public string Name { get; set; }

    // ... Other fields here...
}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<RepoDocument>().ToTable("RepoDocument");
        modelBuilder.Entity<Document>().ToTable("DocumentRecord");
    }

【讨论】:

    【解决方案2】:

    我想,如果您的子类(顺便说一句,我第一次将子类视为后代)用作实体,则您不能 - 它将存储在单独的表中,但您的 RepoDocument 将没有在这种情况下的关键。

    我不确定,如果可能的话,您是否将DocumentRecord 注册为ComplexType,但您可以尝试。在这种情况下,它将存储在同一个表中,所以听起来可能。

    您可以为配置创建单独的类型,然后将其添加到 OnModelCreating 中。

    public class DocumentRecordConfiguration: ComplexTypeConfiguration<DocumentRecord> 
    {
        public DocumentRecordConfiguration()
        {
             /* use fluent api here */
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      相关资源
      最近更新 更多