如何使用Fluent API将子类的Property设置为主键

时间:2015-08-06 16:04:42

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

这是我的模型

  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模型的主键。

我在db上下文中使用此代码:

  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 =&gt; c.Document.Id&#39;无效。表达式应代表一个属性:C#:&#39; t =&gt; t.MyProperty&#39; VB.Net:&#39;功能(t)t.MyProperty&#39;。指定多个属性时,请使用匿名类型:C#:&#39; t =&gt;新的{t.MyProperty1,t.MyProperty2}&#39; VB.Net:&#39;功能(t)新增{T.MyProperty1,t.MyProperty2}&#39;。

问题

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

2 个答案:

答案 0 :(得分:2)

我想,你不能,如果你的子类(顺便说一下,我已经把子类作为第一次的后代读取)用作实体 - 它将被存储在单独的表中,但你的{{1}在这种情况下将没有密钥。

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

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

OnModelCreating

答案 1 :(得分:2)

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

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");
    }