One-to-one-optional self-referencing relationship

c# entity-framework-core


I faced the following domain model

public class Transaction
    public Guid Id { get; set; }
    public decimal TransactionSum { get; set; }
    public decimal TransactionCurrencyConversionRatio { get; set; }
    public bool IsTransactionApprovedBySystem { get; set; }
    public bool IsTransactionApprovedBySender { get; set; }
    public DateTime TransactionInitiatedDate { get; set; }
    public DateTime ? TransactionApprovedDate { get; set; }
    public TransactionType TransactionType { get; set; }

    public Account SenderAccount { get; set; }
    public Account ReceiverAccount { get; set; }
    public Guid SenderAccountId { get; set; }
    public Guid ReceiverAccountId { get; set; }
    public Transaction CommissionTransactionForRealTransaction { get; set; }
    public Guid ? CommissionTransactionForRealTransactionId { get; set; }

It means, that every transaction is Client-to-Client transaction OR CommssionFee transaction(commision for transaction between client-to-client transaction), it described in TransactionType property, which is enum type.

Example: Bob transfer 100$ to Alice, system charge 1$ for this transfer service, so 2 rows added for this operation:

Transaction #XXX1 - 100$ and it has type Client-To-Client and property CommissionTransactionForRealTransaction is NULL, therefore CommissionTransactionForRealTransactionId attribute in table set to NULL.

Transaction #XXX2 - 1$ and it had type CommissionFee, and property CommissionTransactionForRealTransaction is referencing another object, while CommissionTransactionForRealTransactionId in table has some foreign key.

I read documentation and examples in MSDN on EF Core relationship section, but have no idea how to implement 0...1 to 1 self-referencing. I started with this code:

builder.HasOne(p => p.CommissionTransactionForRealTransaction)
    .WithOne(p => p.???);
2/2/2019 12:27:24 PM

Accepted Answer

Write your fluent API configuration as follows:

builder.HasOne(tr => tr.CommissionTransactionForRealTransaction)
       .WithOne().HasForeignKey<Transaction>(tr => tr.CommissionTransactionForRealTransactionId)

It should work for you.

2/2/2019 3:34:43 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow