【发布时间】:2015-04-29 22:12:56
【问题描述】:
我只想更新对象 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);
}
}
添加1:
我稍微更改了代码,我正在读取所有导航字段/对象,特别是对于未完全填充与数据库中相同数据的帐单地址。
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;
仍然显示相同的错误。对我来说,如果我没有从 db 附加所有属性,第 2 点应该可以工作,但它不起作用。
【问题讨论】:
-
我已经回答了为什么您在尝试更改复杂类型的状态时遇到问题。我刚刚注意到您的代码存在另一个问题。当您这样做
Context.Entry(payment).State = EntityState.Modified;时,您实际上使if (Context.Entry(payment).State == EntityState.Detached)下面的行始终为假。一个实体不能同时处于两种状态(您正在测试相同的属性,即您刚刚更改的属性)。 -
请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
标签: c# entity-framework