gpt4 book ai didi

.net - 如何停止 self 跟踪实体执行添加而不是更新

转载 作者:行者123 更新时间:2023-12-01 04:11:22 25 4
gpt4 key购买 nike

提前为这个问题的长度道歉!

我有一个数据结构,从中创建了以下实体数据模型(表/字段已重命名和简化以便于理解!):

Entity Model
PaymentMethod/ProductPaymentMethod结构存在是因为 Customer可以有多个 PaymentMethods可用,但可以根据 Product 从中选择要使用的.
CustomerReference , ProductReferenceVendorReference都是基于CustomerId生成的所以必须在初始保存后更新。
ProductPaymentMethods需要 PaymentMethodIds所以必须在初始保存后添加。
ADO.NET Self-Tracking Entity Generator已运行以生成自跟踪上下文和对象类。

我有一个 CreateCustomer BLL 中生成新实体的方法如下(伪代码):

Customer newCustomer = new Customer()
Product newProduct = new Product()
Vendor newVendor = new Vendor()
List<Currency> newCurrencies = new List<Currency> { new Currency(), new Currency() }
List<Frequency> newFrequencies = new List<Frequency> { new Frequency(), new Frequency() }
List<PaymentMethod> newPaymentMethods = new List<PaymentMethod> { new PaymentMethod(), new PaymentMethod() }
newProduct.Vendors.Add(newVendor)
newProduct.Currencies.Add(newCurrencies)
newProduct.Frequencies.Add(newFrequencies)
newCustomer.Products.Add(newProduct)
newCustomer.PaymentMethods.Add(newPaymentMethods)
newCustomer然后传递给 CreateCustomer DAL 中执行此操作的方法:
context.Customers.AddObject(customer)
context.SaveChanges()
return customer

返回分配给新的 Customer BLL 中的对象和从 CustomerId 生成的引用并补充说:
savedCustomer.CustomerReference = generatedCustomerReference
savedCustomer.Products.First().ProductReference = generatedProductReference
savedCustomer.Products.First().Vendors.First().VendorReference = generatedVendorReference
savedCustomer.PaymentMethod集合循环创建 List<ProductPaymentMethod> productPaymentMethods使用 PaymentMethodIds .然后添加:
savedCustomer.ProductPaymentMethods.Add(productPaymentMethods)
newCustomer然后传递给 UpdateCustomer DAL 中执行此操作的方法:
context.Customers.ApplyChanges(customer)
context.SaveChanges()
return customer

然后返回到表示层

这导致所有已创建然后更新的内容重复 - 我最终会得到 2 x Customer , 2 x Product , 2 x Vendor , 4 x PaymentMethod , 4 x Currency和 4 x Frequency记录 - UpdateCustomer正在接收标记为 Added 的实体

因此,经过一番研究后,我在调用 UpdateCustomer 之前添加了以下内容:
savedCustomer.MarkAsModified()
savedCustomer.Products.First().MarkAsModified()
savedCustomer.Products.First().Vendors.First().MarkAsModified()

这停止了​​重复的 Customer , ProductVendor但我仍然被复制 Currency , FrequencyPaymentMethod记录。

我想出的解决方案是循环遍历每个集合并将每个实体标记为未更改,然后再调用 UpdateCustomer :
foreach (currency in Customer.Products.First().Currencies)
currency.MarkAsUnchanged()

(重复 Customer.PaymentMethodsCustomer.Products.First().Frequencies )

我现在没有重复,我所有的数据都被创建了。

最后,回到我的问题!

我不禁觉得我在这里错过了一些东西。在每次更新之前,我是否真的必须检查关系树的每个部分并根据需要标记为 Modified 或 UnChanged(Microsoft 中的术语组合!)?

我认为术语“自我跟踪”意味着所有这些都应该自动处理。

这是使用 EF/STE 的正确方法还是有更好的方法?

编辑:关于我的 Visual Studio 解决方案的更多信息。

DAL 项目 - CustomerModel.edmx、CustomerModel.Context.tt 和 CustomerDAL.cs

模型项目 - CustomerModel.tt

BLL 项目 - CustomerBLL.cs

WCF 项目 - CustomerWCF.svc.cs

测试项目 CustomerTest.cs

CustomerTest.cs 使用 Private Accessor 调用 CustomerWCF.svc.cs

CustomerWCF.svc.cs 调用 CustomerBLL.cs

CustomerBLL.cs 调用 CustomerDAL.cs

DAL 引用模型

BLL 引用 DAL 和模型

服务引用 BLL 和模型

测试引用服务、BLL 和模型

我应该针对 ServiceReference 而不是 PrivateAccessor 进行测试吗?

最佳答案

如果 EF 认为它是一个新对象,则执行添加,如果认为它是现有对象,则执行更新。

如果您在代码中创建一个对象,使用 new ... 则 EF 假定它是一个新对象。

如果您从数据库中获取一个对象,更改值然后进行保存,EF 就会知道它是一个现有对象并将进行更新。

因此,如果您有一个已在代码中创建但可能存在于数据库中的对象,则必须首先从数据库中检索它,更新它,然后进行保存。

关于.net - 如何停止 self 跟踪实体执行添加而不是更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6059630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com