2

我正在学习实体框架并在删除记录时与 TPH 作斗争。我创建了如下 POCO

 public class Transaction
    {
        public int Id { get; set; }
        public DateTime TransactionDate { get; set; }
        public string Item { get; set; }
        public double Amount { get; set; }
        public virtual PaymentDetail PaymentDetail { get; set; }
    }
    public class Income : Transaction
    {
        public string Source { get; set; }
    }
    public class Expense : Transaction
    {
        public bool IsAvoidable { get; set; }
    }
    public class PaymentDetail
    {
        public int Id { get; set; }
        public DateTime PaymentDate { get; set; }
    }

    public class Cash : PaymentDetail
    {
    }    
    public class BankTransfer : PaymentDetail
    {
        public string TransactionNumber { get; set; }
    }    
    public class BankCheque : PaymentDetail
    {
        public string ChequeNumber { get; set; }
    }
    public class Card : PaymentDetail
    {
        public BankAccount BankAccount { get; set; }
    }

在我的 DbContext 中,我重写了 OnModelCreating 方法。我在那里有以下代码。

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

        modelBuilder.Entity<User>().ToTable("User");
        modelBuilder.Entity<Transaction>().ToTable("Transaction");
        modelBuilder.Entity<Income>().ToTable("Income");
        modelBuilder.Entity<Expense>().ToTable("Expense");
        modelBuilder.Entity<PaymentDetail>().ToTable("PaymentDetail");
        modelBuilder.Entity<Liability>().ToTable("Liability");

        modelBuilder.Entity<Transaction>().HasOptional(p => p.PaymentDetail);
    }

我已经编写了插入和更新事务的代码。插入工作正常。它使用 paymentDetail(作为现金)创建交易。但是当我更新它并将 PaymentDetail 更改为 BankTransfer 时,它会更新 PaymentDetail 中的详细信息(这是一个作为 TPH 创建的平面表)。但它不会更改鉴别器列。它仍然是 Cash,因为它最初是使用 Cash 类型创建的。我通过谷歌搜索发现鉴别器列没有改变。所以我试图删除该行,但它现在给出了以下错误

DELETE 语句与 REFERENCE 约束“FK_dbo.Transaction_dbo.PaymentDetail_PaymentDetail_Id”冲突。冲突发生在数据库“MyRecordsDB”、表“dbo.Transaction”、列“PaymentDetail_Id”中。该语句已终止。

EF代码创建的TransactionTable首先有PaymentDetail_ID可以有allow null,那么谁能告诉我这个问题吗?

在这种情况下使用 TPH 好不好?

以下是从我的 RepositoryClass 修改 Transaction 的方法供参考。

    public Transaction ModifyTransaction(Transaction tran)
    {
        using (_ctx = new Context())
        {       
            tran = _ctx.Transactions.Attach(tran);

            //Check if the Payment detail is modified
            if(tran.PaymentDetail != null)
            {
                PaymentDetail currentPaymentDetail = null;
                using (var ctx = new Context())
                {
                    currentPaymentDetail = ctx.PaymentDetails.Where(p => p.Id == tran.PaymentDetail.Id).FirstOrDefault();    

                    if (currentPaymentDetail.GetType() != tran.PaymentDetail.GetType())
                    {
                        //Remove current payment detail record
                        ctx.PaymentDetails.Remove(currentPaymentDetail);
                        ctx.SaveChanges();
                         _ctx.Entry<PaymentDetail>(tran.PaymentDetail).State = EntityState.Added;
                    }
               }                                          
            }
            else
            {
                //Do not modify the Payment detail
                _ctx.Entry<PaymentDetail>(tran.PaymentDetail).State = EntityState.Unchanged;
            }   


            _ctx.Entry<Transaction>(tran).State = EntityState.Modified;                
            _ctx.Entry<Profile>(tran.profile).State = EntityState.Unchanged;
            _ctx.SaveChanges();
        }
        return tran;
    }
4

0 回答 0