EF:对象更新过程未更改一个属性的值 [英] EF: object update process is not changing value of one property
问题描述
我的应用程序有2个类: PaymentMethod
& Currency
( Currency
是 PaymentMethod
的属性)。当我的应用程序确实更新了 PaymentMethod
且新值为 Currency
属性时(该值已存在于db中,但已分配给 PaymentMethod
),在 SaveCHanges
方法之后, Currency
属性仍然包含旧值。 为什么?:)
my application has 2 classes: PaymentMethod
& Currency
(Currency
is property of PaymentMethod
). When my app does update of PaymentMethod
with new value of Currency
propery (value already exists in db but it's being assigned to PaymentMethod
), after SaveCHanges
method, Currency
property still contains old value. WHY?:)
这是我的应用替换货币对象值的方式:
this is how my application replaces Currency object value:
if (String.Compare(existingPaymentMethod.Currency.Code, mwbepaymentmethod.CurrencyCode, true) !=0)
{
var readCurrency = currencyRepo.FindByCode(mwbepaymentmethod.CurrencyCode);
existingPaymentMethod.Currency = readCurrency;
}
paymentMethodRepository.Save(ref existingPaymentMethod);
return true;
PaymentMethod
& 货币
类:
public class PaymentMethod : BaseEntity
{
public enum MethodTypeEnum
{
Creditcard,
Virtualcard,
Wallet
};
public MethodTypeEnum MethodType { get; set; }
public int VendorId { get; set; }
public virtual Address BillingAddress { get; set; }
public virtual Currency Currency { get; set; }
}
public class Currency : BaseEntity
{
[JsonProperty("code")]
[Key]
public string Code { get; set; }
[JsonProperty("symbol")]
public string Symbol { get; set; }
[JsonIgnore]
public virtual ICollection<Payment> Payments { get; set; }
[JsonIgnore]
public virtual ICollection<PaymentMethod> PaymentMethods { get; set; }
}
编辑方法:
public override void Edit(MwbePaymentMethod entityToUpdate)
{
DbSet.Attach(entityToUpdate);
Context.Entry(entityToUpdate).State = EntityState.Modified;
//manual update of properties
//Context.Entry(entityToUpdate.BillingAddress).State = EntityState.Modified;
//Context.Entry(entityToUpdate.Currency).State = EntityState.Unchanged;
}
OnModelCreating
方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MobileWalletContext>());
...
modelBuilder.Entity<MwbePaymentMethod>().HasRequired(e => e.Currency).WithMany(e => e.PaymentMethods);
base.OnModelCreating(modelBuilder);
}
Autofac定义的数据库上下文:
DB context defined by Autofac:
builder.RegisterType<MobileWalletContext>().As<IMwbeDbContext>().InstancePerRequest();
更新1 :
EF日志未显示货币字段更新:
Update 1: EF logs shows no currency field update:
UPDATE [dbo].[MwbeAddress] SET [Street] = @0, [City] = @1, [ZipCode] = @2, [Country] = @3 WHERE ([Id] = @4)
-- @0: 'FFFF12' (Type = String, Size = -1)
-- @1: 'GlasgowSSSS' (Type = String, Size = -1)
-- @2: 'B33 8TH' (Type = String, Size = -1)
-- @3: 'England' (Type = String, Size = -1)
-- @4: '2' (Type = Int32)
-- Executing at 2015-07-13 07:35:48 +02:00
-- Completed in 39 ms with result: 1
UPDATE [dbo].[MwbePaymentMethod] SET [MethodType] = @0, [VendorId] = @1, [Number] = @2, [ExpirationDate] = @3, [Balance] = @4, [IsPending]
= @5, [IsDefault] = @6 WHERE ([Id] = @7)
-- @0: '1' (Type = Int32)
-- @1: '0' (Type = Int32)
-- @2: '4444 4444 4444 4450' (Type = String, Size = -1)
-- @3: '2015-10-10 00:00:00' (Type = DateTime2)
-- @4: '0' (Type = Double)
-- @5: 'True' (Type = Boolean)
-- @6: 'False' (Type = Boolean)
-- @7: '3' (Type = Int32)
-- Executing at 2015-07-13 07:35:48 +02:00
-- Completed in 7 ms with result: 1
为什么没有更新 Currency
属性?
Why there is not update for Currency
property?
推荐答案
设置实体的状态(已添加
除外)仅影响实体的标量属性,而不影响其导航属性,其 associations 。
Setting an entity's state (other than Added
) only affects the entity's scalar properties, not its navigation properties, its associations.
因此,您有三个选择:
将货币附加到上下文。在您的 Edit
方法中:
Attach the currency to the context. In your Edit
method:
Context.Entry(entityToUpdate).State = EntityState.Modified;
Context.Entry(entityToUpdate.Currency).State = EntityState.Unchanged;
现在EF知道分配给<$ c的货币
$ c> PaymentMethod ,因此它知道关联已更改,它将更新数据库中的外键。
Now EF knows the Currency
that is assigned to PaymentMethod
, so it knows the association changed, and it will update the foreign key in the database.
但是我不要以为这样对您有用。从您的问题陈述中,我了解到 currencyRepo
和 paymentMethodRepository
不会共享相同的上下文,否则您将不会拥有首先遇到问题(货币已经附加)。您不能将一个实体附加到两个上下文中,因此 currencyRepo
的上下文应在此时处理,或者您首先应将货币与其分离。
But I don't think this is going to work for you just like that. From your problem statement I understand that currencyRepo
and paymentMethodRepository
don't share the same context, otherwise you wouldn't have had the problem in the first place (the currency would already be attached). You can't attach an entity to two contexts, so either currencyRepo
's context should be disposed at that point, or you should detach the currency from it first. Pretty laborious.
让 currencyRepo
和 paymentMethodRepository
(以及该问题的所有存储库)在一个工作单元中共享同一上下文实例。无论如何,建议这样做,不仅是为了解决这个问题。
Let currencyRepo
and paymentMethodRepository
(and all repositories for that matter) share the same context instance within one unit of work. This is recommended anyway, not only to solve this problem.
不要设置货币
属性,但添加原始外键属性 PaymentMethod.CurrencyId
并在币种更改时修改该属性。这是一个标量属性,因此它将响应设置 EntityState.Modified
。
Don't set the Currency
property, but add a primitive foreign key property PaymentMethod.CurrencyId
and modify that property if the currency changes. This is a scalar property, so it will respond to setting EntityState.Modified
.
这篇关于EF:对象更新过程未更改一个属性的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!