EF Code第一个TPH,当类型改变时不更新鉴别器列

时间:2014-01-01 09:51:38

标签: entity-framework insert-update discriminator tph

我正在学习实体框架,并在删除记录时与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的平面表)。但它不会改变鉴别器列。它仍然是首次使用现金类型创建的现金。 我通过谷歌搜索发现Discriminator列没有改变。所以我试图删除该行,但它现在给出了以下错误

  

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

由EF代码创建的TransactionTable首先具有PaymentDetail_ID可以允许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;
    }

0 个答案:

没有答案