EF Code первый TPH, не обновляет столбец дискриминатора при изменении типа

Я изучаю структуру Entity и борюсь с 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 (как Cash). Но когда я обновляю его и меняю PaymentDetail на BankTransfer, он обновляет детали в PaymentDetail (это плоская таблица, созданная как TPH). но это не меняет столбец дискриминатора. Денежные средства остаются такими же, какими они были впервые созданы с типом "Наличные". По поиску, я обнаружил, что столбец Дискриминатор не меняется. Поэтому я попытался удалить эту строку, но теперь выдает следующее сообщение об ошибке

Оператор DELETE конфликтует с ограничением REFERENCE "FK_dbo.Transaction_dbo.PaymentDetail_PaymentDetail_Id". Конфликт произошел в базе данных "MyRecordsDB", таблице "dbo.Transaction", столбце "PaymentDetail_Id". Заявление было прекращено.

TransactionTable, созданный кодом EF, вначале имеет PaymentDetail_ID, может иметь значение null, затем кто-нибудь может сказать, пожалуйста, это проблема?

Хорошо ли использовать TPH в таких случаях?

Для справки ниже приведен метод для модификации транзакции из моего RepositoryClass.

    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 ответов

Другие вопросы по тегам