一对一EF,其中一个对象具有复合键

时间:2016-12-10 15:01:04

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

我有

public class Expense
{
    public int Id { get; private set; }

    [ForeignKey("AccountId")]
    public virtual Account Account { get; private set; }

    [Required]
    public int AccountId { get; private set; }

    public virtual ExpenseCategory ExpenseCategory { get; private set; }

    public Expense(... params ...)
    {
        this.ExpenseCategory = new ExpenseCategory();
    }

    protected Expense()
    {
    }
}

public class Account
{
    [Key]
    public int Id { get; private set; }

    public virtual List<Expense> Expenses { get; private set; }

    ...
}

public class ExpenseCategory
{
    [ForeignKey("CategoryId")]
    public virtual BaseCategory Category { get; private set; }

    public Guid? CategoryId { get; private set; }

    public virtual Expense Expense { get; private set; }

    [Key, ForeignKey("Expense")]
    public int ExpenseId { get; private set; }

    // EF is a 'friend' assembly, don't worry about the internal
    internal ExpenseCategory()
    {
    }
}

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

    // This deletes the Expense entity when it is removed from the Account
    modelBuilder.Entity<Expense>()
        .HasKey(t => new { t.Id, t.AccountId })
        .Property(t => t.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    // PROBLEM STARTS HERE MAYBE
    modelBuilder.Entity<ExpenseCategory>()
            .HasKey(e => e.ExpenseId);

    modelBuilder.Entity<Expense>()
            .HasRequired(s => s.ExpenseCategory)
            .WithRequiredPrincipal(tc => tc.Expense);
}

我在费用和帐户之间的关系很好 - 它完全按照我的需要运作。我现在正试图以1:1(我知道MSSQL本身不支持它,但EF解决了这个问题)与Expense和Category之间的关系。我希望ExpenseCategory成为Expense和Category之间的映射。每个Expense必须只有一个ExpenseCategory,我希望该映射的Key成为Expense的ID。

我遇到麻烦,我尝试过任何事情。通过当前的设置,我得到了:

  

a中的从属角色和主要角色中的属性数   关系约束必须相同。

我认为问题可能来自费用上的复合键。

任何帮助?

1 个答案:

答案 0 :(得分:0)

想出来。在我的ExpenseCategory

上添加了以下内容
public int AccountId { get; private set; }

以下Fluent API:

modelBuilder.Entity<ExpenseCategory>()
    .HasKey(e => new { e.ExpenseId, e.AccountId });

modelBuilder.Entity<Expense>()
            .HasRequired(s => s.ExpenseCategory)
            .WithRequiredPrincipal(tc => tc.Expense)
            .WillCascadeOnDelete(true);