C# 同一个表上有多个外键。如何重新设计我的模型?

C# 同一个表上有多个外键。如何重新设计我的模型?,c#,asp.net-core,ef-core-3.1,C#,Asp.net Core,Ef Core 3.1,我想用EF Core创建一个简单的MoneyTransaction模型,如下所示,我遇到了以下错误: Microsoft.EntityFrameworkCore.dll中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理:“无法在“Member.MoneyTransactions”和“MoneyTransaction.PaidBy”之间创建关系,因为“Member.MoneyTransactions”和“MoneyTransaction.Ch

我想用EF Core创建一个简单的MoneyTransaction模型,如下所示,我遇到了以下错误:

Microsoft.EntityFrameworkCore.dll中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理:“无法在“Member.MoneyTransactions”和“MoneyTransaction.PaidBy”之间创建关系,因为“Member.MoneyTransactions”和“MoneyTransaction.ChargedBy”之间已存在关系。”。导航属性只能参与单个关系。如果要覆盖“OnModelCreating”中导航“MoneyTransaction.PaidBy”的第一个上的现有关系调用“Ignore”

以下是我迄今为止编写的代码:

public class Member
{
    // ...
    public string MoneyTransactionsId { get; set; }
    public ICollection<MoneyTransaction> MoneyTransactions { get; set; } = new List<MoneyTransaction>();
    // ...
}

public class MoneyTransaction
{
    // ...
    public string PaidById { get; set; }
    public Member PaidBy { get; set; }
    public string ChargedById { get; set; }
    public Member ChargedBy { get; set; }
    // ...
}
公共类成员
{
// ...
公共字符串MoneyTransactionId{get;set;}
公共ICollection MoneyTransactions{get;set;}=new List();
// ...
}
公共类货币交易
{
// ...
公共字符串PaidById{get;set;}
公共成员PaidBy{get;set;}
公共字符串ChargedById{get;set;}
由{get;set;}计费的公共成员
// ...
}
问题发生在onmodel创建中:

protected override void OnModelCreating(ModelBuilder builder)
{
    // ...
    builder.Entity<Member>()
        .HasMany(m => m.MoneyTransactions)
        .WithOne(t => t.PaidBy)
        .HasForeignKey(t => t.PaidById)
        .OnDelete(DeleteBehavior.NoAction)
        .HasPrincipalKey(m => m.Id);
    builder.Entity<Member>()
        .HasMany(m => m.MoneyTransactions)
        .WithOne(t => t.ChargedBy)
        .HasForeignKey(t => t.ChargedById)
        .HasPrincipalKey(m => m.Id);
    // ...
}
模型创建时受保护的覆盖无效(ModelBuilder)
{
// ...
builder.Entity()
.HasMany(m=>m.MoneyTransactions)
.WithOne(t=>t.PaidBy)
.HasForeignKey(t=>t.PaidById)
.OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(m=>m.Id);
builder.Entity()
.HasMany(m=>m.MoneyTransactions)
.带一个(t=>t.充电方式)
.HasForeignKey(t=>t.ChargedById)
.HasPrincipalKey(m=>m.Id);
// ...
}

我不确定如何设计我的模型,使其仅通过fluentapi工作(不希望在模型类中有数据注释)。这可能是一个简单的解决方案,但不知何故,我找不到任何有用的东西来重构我的模型以使其工作。

由于
成员既可以在交易中收费,也可以在交易中付款,因此它应该有两个
MoneyTransaction
列表-一个是他们收费的,另一个是他们付费的-

公共类成员
{
// ...
公共字符串MoneyTransactionId{get;set;}
public ICollection ChargedTransactions{get;set;}=new List();
public ICollection PaidTransactions{get;set;}=new List();
// ...
}
然后您可以将它们配置为-

builder.Entity()
.HasMany(m=>m.PaidTransactions)
.WithOne(t=>t.PaidBy)
.HasForeignKey(t=>t.PaidById)
.OnDelete(DeleteBehavior.NoAction)
.HasPrincipalKey(m=>m.Id);
builder.Entity()
.HasMany(m=>m.ChargedTransactions)
.带一个(t=>t.充电方式)
.HasForeignKey(t=>t.ChargedById)
.HasPrincipalKey(m=>m.Id);

会员
模型中的
货币交易
应该代表什么?他们支付的交易清单,还是他们收取的交易清单?你可以买一个。或者您必须在
成员
中定义另一个集合。它应该表示用户x从用户y(付款人)收取的交易列表,然后
成员
应该有两个集合。一个用于他们收取的交易,一个用于他们支付的交易。啊,是的,这将是一个解决方案,但不可能通过一个集合来解决这个问题?一个集合可以与
PaidBy
ChargedBy
模型中的
引用相关。因此,它将只跟踪一种类型的交易-支付或收费。要跟踪这两种类型的事务,您需要两个集合。