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;
}