EF:对象更新过程不会更改一个属性的值
我的应用程序有2个类: PaymentMethod
& Currency
( Currency
是PaymentMethod
属性)。 当我的应用程序使用Currency
PaymentMethod
的新值更新PaymentMethod
时(值已经存在于db中,但它被分配给PaymentMethod
),在SaveCHanges
方法之后, Currency
属性仍包含旧值。 为什么?:)
这是我的应用程序替换Currency对象值的方式:
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
和Currency
类:
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 Payments { get; set; } [JsonIgnore] public virtual ICollection 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()); ... modelBuilder.Entity().HasRequired(e => e.Currency).WithMany(e => e.PaymentMethods); base.OnModelCreating(modelBuilder); }
Autofac定义的DB上下文:
builder.RegisterType().As().InstancePerRequest();
更新1 :EF日志显示没有货币字段更新:
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
属性的更新?
设置实体的状态(除了已Added
)仅影响实体的标量属性 ,而不影响其导航属性及其关联 。
所以你有三个选择:
选项1
将货币附加到上下文。 在您的Edit
方法中:
Context.Entry(entityToUpdate).State = EntityState.Modified; Context.Entry(entityToUpdate.Currency).State = EntityState.Unchanged;
现在EF知道分配给PaymentMethod
的Currency
,因此它知道关联已更改,并且它将更新数据库中的外键。
但我不认为这对你有用。 从您的问题陈述中我理解currencyRepo
和paymentMethodRepository
不共享相同的上下文,否则您首先不会遇到问题(货币已经附加)。 您不能将实体附加到两个上下文,因此应该在该点处处理currencyRepo
的上下文,或者您应该首先从中分离货币。 非常费力。
选项2
让currencyRepo
和paymentMethodRepository
(以及所有相关的存储库)在一个工作单元内共享相同的上下文实例。 无论如何,这是推荐的,不仅是为了解决这个问题。
选项3
不要设置Currency
属性,而是添加原始外键属性PaymentMethod.CurrencyId
并在货币更改时修改该属性。 这是一个标量属性,因此它将响应设置EntityState.Modified
。
DbSet.Attach
不是递归的。 您需要附加所有已调入的实体:
public override void Edit(MwbePaymentMethod entityToUpdate) { DbSet.Attach(entityToUpdate); Context.Entry(entityToUpdate).State = EntityState.Modified; if(entityToUpdate.BillingAddress != null) { DbSet.Attach(entityToUpdate.BillingAddress); Context.Entry(entityToUpdate.BillingAddress).State = EntityState.Modified; } if(entityToUpdate.Currency != null) { DbSet.Attach(entityToUpdate.Currency); Context.Entry(entityToUpdate.Currency).State = EntityState.Modified; } //manual update of properties //Context.Entry(entityToUpdate.BillingAddress).State = EntityState.Modified; //Context.Entry(entityToUpdate.Currency).State = EntityState.Unchanged; }
此问题是由于在PaymentMethod类中未定义的外键关系。 需要指定这样的特定列将用于更新,如果货币是新的,那么将插入,并且将针对货币代码保存相同的代码。
上述就是C#学习教程:EF:对象更新过程不会更改一个属性的值分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
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 string CurrencyCode {get;set;} //Replace with actual column name [ForeignKey("CurrencyCode ")] public virtual Currency Currency { get; set; } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/982907.html