c# – 在Entity Framework 5中重写SaveChanges首先复制旧的旧版
我们公司提供一套操作数据库中的数据的各种应用程序.每个应用程序都有其特定的业务逻辑,但所有应用程序都共享一个常见的业务规则子集.常见的东西在一堆使用“经典ADO”(通常称为存储过程,有时使用动态SQL)的C中编写的遗留COM DLL中.大多数这些DLL具有基于
XML的方法(更不用说基于专有格式的方法!)来创建,编辑,删除和检索对象,还有一些额外的操作,例如快速复制和转换许多实体的方法.
中间件DLL现在很老了,我们的应用程序开发人员需要一个可以很容易地被C#应用程序使用的新的面向对象(不是面向对象的)中间件. 所以我试图为一个简化的场景创建一个模型(真实场景要复杂得多,在这里我将发布简化场景的简化子集).我使用Visual Studio 2010,实体框架5代码第一,SQL Server 2008 R2. bool Edit(string xmlstring,out string errorMessage) 使用如下格式: <ORDER> <ID>234</ID> <NAME>SuperFastCar</NAME> <QUANTITY>3</QUANTITY> <LABEL>abc</LABEL> </ORDER> 编辑方法实现了以下业务逻辑:当数量更改时,必须对所有具有相同标签的订单应用“自动缩放”. 如何用POCO类和实体框架复制?这是一个问题,因为旧的编辑方法一次只能更改一个订单 我试图通过覆盖SaveChanges来实现它. POCO类: using System; namespace MockOrders { public class Order { public Int64 Id { get; set; } public string Name { get; set; } public string Label { get; set; } public decimal Quantity { get; set; } } } 迁移文件(创建索引): namespace MockOrders.Migrations { using System; using System.Data.Entity.Migrations; public partial class UniqueIndexes : DbMigration { public override void Up() { CreateIndex("dbo.Orders","Name",true /* unique */,"myIndex1_Order_Name_Unique"); CreateIndex("dbo.Orders","Label",false /* NOT unique */,"myIndex2_Order_Label"); } public override void Down() { DropIndex("dbo.Orders","myIndex2_Order_Label"); DropIndex("dbo.Orders","myIndex1_Order_Name_Unique"); } } } 的DbContext: using System; using System.Data.Entity; using System.Data.Entity.ModelConfiguration; using System.Linq; namespace MockOrders { public class MyContext : DbContext { public MyContext() : base(GenerateConnection()) { } private static string GenerateConnection() { var sqlBuilder = new System.Data.SqlClient.SqlConnectionStringBuilder(); sqlBuilder.DataSource = @"localhostaaaaaa"; sqlBuilder.InitialCatalog = "aaaaaa"; sqlBuilder.UserID = "aaaaa"; sqlBuilder.Password = "aaaaaaaaa!"; return sqlBuilder.ToString(); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new OrderConfig()); } public override int SaveChanges() { ChangeTracker.DetectChanges(); var groupByLabel = from changedEntity in ChangeTracker.Entries<Order>() where changedEntity.State == System.Data.EntityState.Modified && changedEntity.Property(o => o.Quantity).IsModified && changedEntity.Property(o => o.Quantity).OriginalValue != 0 && !String.IsNullOrEmpty(changedEntity.Property(o => o.Label).CurrentValue) group changedEntity by changedEntity.Property(o => o.Label).CurrentValue into x select new { Label = x.Key,List = x}; foreach (var labeledGroup in groupByLabel) { var withScalingFactor = from changedEntity in labeledGroup.List select new { ChangedEntity = changedEntity,ScalingFactor = changedEntity.Property(o => o.Quantity).CurrentValue / changedEntity.Property(o => o.Quantity).OriginalValue }; var groupByScalingFactor = from t in withScalingFactor group t by t.ScalingFactor into g select g; // if there are too many scaling factors for this label,skip automatic scaling if (groupByScalingFactor.Count() == 1) { decimal scalingFactor = groupByScalingFactor.First().Key; if (scalingFactor != 1) { var query = from oo in this.AllTheOrders where oo.Label == labeledGroup.Label select oo; foreach (Order ord in query) { if (this.Entry(ord).State != System.Data.EntityState.Modified && this.Entry(ord).State != System.Data.EntityState.Added) { ord.Quantity = ord.Quantity * scalingFactor; } } } } } return base.SaveChanges(); } public DbSet<Order> AllTheOrders { get; set; } } class OrderConfig : EntityTypeConfiguration<Order> { public OrderConfig() { Property(o => o.Name).HasMaxLength(200).IsRequired(); Property(o => o.Label).HasMaxLength(400); } } } 它似乎工作(当然是阻止bug),但这只是一个例子:只有一个类:一个真正的生产应用程序可能有数百个类! 有不同的方法吗?我错过了什么吗? 非常感谢你! 德梅特里奥 附:顺便说一下,覆盖SaveChanges并注册到“SavingChanges”事件之间有什么不同吗?我阅读了这份文件,但并没有解释是否有区别: 这篇文章: 说“当覆盖SaveChanges时,您可以在调用base.SaveChanges之前和之后放置自定义逻辑.但还有其他注意事项/优点/缺点? 解决方法
我会说这个逻辑属于你的MockOrders.Order类,在一个使用你的Order类(例如BusinessLogic.Order)或Label类的更高层的类中.听起来像你的标签作为一个加入属性,所以,不知道的细节,我会说拉出来,使它成为一个自己的实体,这将给你导航属性,所以你可以更自然地访问所有订单与相同的标签.
如果修改数据库以使规范化标签不是一个参与者,那么建立一个视图,并将其带入您的实体模型中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |