Я хочу обновить только простые свойства объекта MwbePaymentMethod, без сложных свойств (4 последних свойства являются сложными), поэтому он изменяет эти 4 комплексных свойства на неизмененные. Но метод Edit терпит неудачу в строке:Обновление сложного объекта в контексте БД
Context.Entry(payment.BillingAddress).State = EntityState.Unchanged;
с ошибкой:
Прикрепление объект типа «MobileWallet.Common.Repository.MwbeAddress» не удалось, так как другой объект того же типа, уже имеет один и тот же значение первичного ключа , Это может произойти при использовании метода «Прикрепить» или установки состояния объекта в «Без изменений» или «Модифицировано», если любые объекты на графике имеют конфликтующие значения ключей. Это может быть связано с тем, что некоторые объекты являются новыми и еще не получили значения ключей базы данных. В этом случае используйте метод «Добавить» или «Добавленное» состояние объекта для отслеживания графика, а затем, если необходимо, установите состояние не новых объектов «Без изменений» или «Модифицировано».
Модель объекта:
public class MwbePaymentMethod : BaseEntity
{
public enum MethodTypeEnum
{
Creditcard,
Virtualcard,
Wallet
};
public MethodTypeEnum MethodType { get; set; }
public string Number { get; set; }
public DateTime? ExpirationDate { get; set; }
public double Balance { get; set; }
public bool IsPending { get; set; }
public bool IsDefault { get; set; }
public MwbeAddress BillingAddress { get; set; }
public MwbeCurrency Currency { get; set; }
public MwbeUserData UserData { get; set; }
public DateTime? PaymentDate { get; set; }
[JsonIgnore]
public virtual ICollection<MwbePayment> Payments { get; set; }
}
Изменить метод:
public override void Edit(MwbePaymentMethod payment)
{
if (payment.Currency != null && payment.Currency.Id != 0)
{
Context.Entry(payment.Currency).State = EntityState.Unchanged;
}
if (payment.UserData != null && payment.UserData.Id != 0)
{
Context.Entry(payment.UserData).State = EntityState.Unchanged;
}
if (payment.BillingAddress != null && payment.BillingAddress.Id != 0)
{
Debugger.Break();
Context.Entry(payment.BillingAddress).State = EntityState.Unchanged;
}
Context.Entry(payment).State = EntityState.Modified;
if (Context.Entry(payment).State == EntityState.Detached)
{
DbSet.Attach(payment);
}
}
ADDED1:
Я изменил код немного, Im чтение всех навигационных полей/объект особенно Платежный адрес, который не был полностью заполненными теми же данными, что и в базе данных.
public void UpdateMwbePaymentMethod(MwbePaymentMethodFilter filter, MwbePaymentMethodDtoInOut mwbepaymentmethod)
{
var currentPaymentMethod = paymentMethodRepository.FindBy(x => x.UserData.Id == filter.userId && x.Id == filter.id);
if (currentPaymentMethod == null || currentPaymentMethod.Count() != 1)
{
throw new DBConcurrencyException();
}
var mwbePaymentPethod = Mapper.Map<MwbePaymentMethod>(mwbepaymentmethod);
//load existing user data
mwbePaymentPethod.UserData = userRepository.Get(filter.userId).Data;
//load existing address with subproperties
mwbePaymentPethod.BillingAddress = addressRepository.FindBy(x => x.Id == mwbePaymentPethod.BillingAddress.Id, x=>x.Merchants, x=>x.PaymentMethods, x=>x.Deliveries, x=>x.UserDatas).SingleOrDefault();
if (mwbePaymentPethod.BillingAddress == null)
{
throw new DBConcurrencyException();
}
paymentMethodRepository.Edit(mwbePaymentPethod);
paymentMethodRepository.SaveChanges();
}
И Изменить метод:
public override void Edit(MwbePaymentMethod payment)
{
if (payment.Currency != null && payment.Currency.Id != 0)
{
Context.Entry(payment.Currency).State = EntityState.Unchanged;
}
if (payment.UserData != null && payment.UserData.Id != 0)
{
Context.Entry(payment.UserData).State = EntityState.Unchanged;
}
if (payment.BillingAddress != null && payment.BillingAddress.Id != 0)
{
Debugger.Break(); // tutaj byl ostatnio problem
Context.Entry(payment.BillingAddress).State = EntityState.Unchanged;
}
Context.Entry(payment).State = EntityState.Modified;
}
Независимо от того, если
1) Context.Entry(payment.BillingAddress).State = EntityState.Unchanged;
или
2) Context.Entry(payment.BillingAddress).State = EntityState.Modified;
Отображается та же ошибка. Для меня точка 2) должна работать, если я не привязал все свойства из db, но он не работает.
Я ответил, почему у вас возникают проблемы при попытке изменить состояние сложных типов. Я только что заметил еще одну проблему с вашим кодом. Когда вы делаете это 'Context.Entry (платеж) .State = EntityState.Modified;' вы фактически делаете строку ниже 'if (Context.Entry (платеж) .State == EntityState.Detached)' всегда быть false. Сущность не может находиться в двух состояниях одновременно (вы тестируете одно и то же свойство, которое вы только что изменили). – Rui
См. [«Если вопросы включают« теги »в их названиях?») (Http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), где консенсус «нет, они не должны»! –