当前位置: 首页 > news >正文

宜春市网站建设网站数据迁移教程

宜春市网站建设,网站数据迁移教程,山东省住房和城乡建设厅网站首页,站酷网app实体数据对象状态 在EF环境下#xff0c;应用程序更改数据对象会引发数据集状态的变更#xff0c;可能的状态有以下几种#xff1a; 数据对象状态列表Added添加实体对象创建到实体集中#xff0c;数据未添加进数据库Modified实体对象已经存在于实体数据集中#xff0c;数…实体数据对象状态 在EF环境下应用程序更改数据对象会引发数据集状态的变更可能的状态有以下几种 数据对象状态列表Added添加实体对象创建到实体集中数据未添加进数据库Modified实体对象已经存在于实体数据集中数据库同时存在对应的数据但某些实体对象属性值已经改变未更新到数据库中Deleted实体对象已经存在于实体数据集中数据库同时存在对应的数据但是实体对象本身被标识为删除Unchanged实体对象存在于数据集中数据库同时包含对应未曾更改的相同数据Detached实体对象已经不在数据集中 当SaveChanges方法被调用时 1、Added状态会将新实体对象的属性数据更新到数据库。 2、Modified状态实体对象的属性值就会逐一更新到数据库中对应的数据字段。 3、Deleted则将其中对应实体对象的数据删除。 4、当实体对象为Added或者Modified状态时调用SaveChanges方法更新数据成功后会将状态调整为Unchanged。 5、当实体对象为Deleted状态时调用SaveChanges方法更新数据成功后会将对象的状态调整为Detached。 可以使用DbContext.Entry方法获取对象的状态。 下面有代码说明举例假设存在如下实体类 public class Product{public int Id { get; set; }public string Name { get; set; }public string Category { get; set; }public int Price { get; set; }} 上下文类代码如下图所示 public class SaveChangesModel : DbContext{public SaveChangesModel(): base(nameSaveChangesModel){}public virtual DbSetProduct Product { get; set; }} 运行程序建立相应的数据库和表结构后修改Main函数中的代码如下图所示 static void Main(string[] args) {using (SaveChangesModel db new SaveChangesModel()){Product product new Product{Name 电脑,Category 办公用品,Price 5000,};Console.WriteLine(初始状态{0}, db.Entry(product).State.ToString());db.Product.Add(product);Console.WriteLine(Add后的状态{0}, db.Entry(product).State.ToString());Console.ReadKey();} } 运行后效果如下图所示 可以看到一开始product对象创建完成后是Detached状态表示其与数据库无任何关联调用Add方法后转化成为Added状态表示这一组数据对象当前是准备加入数据库的状态。 EF根据数据对象的状态决定是否进行底层数据库的变更并且通过状态调整达到数据变更的目的。 可以将其中代码部分修改下如下图所示 //db.Product.Add(product); db.Entry(product).State System.Data.Entity.EntityState.Added; 其中直接将Product对象的state设置为Added效果与Add方法相同因此不需要明确调用Add方法只需要通过状态标识即可完成添加操作。  更新与删除  更新和删除操作必须先要找到数据集中相应的数据才能进行操作。 Find()方法可以利用数据表的主键进行快速查询出想要的数据。更新操作的示例代码如下图所示 static void Main(string[] args) {using (SaveChangesModel db new SaveChangesModel()){var product db.Product.Find(1);Console.WriteLine(初始状态{0}, db.Entry(product).State.ToString());product.Price 4500;Console.WriteLine(修改后状态{0}, db.Entry(product).State.ToString());db.SaveChanges();Console.ReadKey();} } 运行结果如下图所示 删除效果的实例代码如下图所示 static void Main(string[] args) {using (SaveChangesModel db new SaveChangesModel()){var product db.Product.Find(1);Console.WriteLine(初始状态{0}, db.Entry(product).State.ToString());db.Product.Remove(product);Console.WriteLine(删除后状态{0}, db.Entry(product).State.ToString());db.SaveChanges();Console.ReadKey();} } 运行结果下图所示  Attach DbSet类定义了一个Attach方法此方法定义接收一个实体数据对象参数将其附加到数据集中等同于将此数据直接从数据库取出并转换成对应的数据对象而附加完成之后entity的状态时Unchanged通过修改其状态即可通过SaveChanges方法变成变更更新操作。 修改Main函数中的方法如下图所示 static void Main(string[] args) {using (SaveChangesModel db new SaveChangesModel()){Product product new Product{Id 1,Name 电脑,Category 办公用品,Price 6000,};Console.WriteLine(初始状态{0}, db.Entry(product).State.ToString());db.Product.Attach(product);Console.WriteLine(Attach后状态{0}, db.Entry(product).State.ToString());db.Entry(product).State System.Data.Entity.EntityState.Modified;Console.WriteLine(Modified后状态{0}, db.Entry(product).State.ToString());Console.ReadKey();} } 运行后结果如下图所示  变更追踪——DbContext.ChangeTracker  DbContext会对实体的更新操作进行追踪如果想要存取变更状态的信息可以通过DbContext.ChangeTracker属性的调用来获取支持追踪功能的DbChangeTracker对象语句如下 DbChangeTracker tracker context.changeTracker DbChangeTracker定义了Entries方法执行这个方法返回的是一个当前DbContext追踪的实体对象其相关的IEnumerableDbEntityEntry集合进一步调用此方法即可逐一取出所有的DbEntityEntry对象并提取所需的实体对象变更信息。  示例代码如下图所示 static void Main(string[] args) {using (SaveChangesModel db new SaveChangesModel()){var product db.Product.Find(1);DbChangeTracker tracker db.ChangeTracker;EntryInfo(tracker, 首次载入);product.Name 惠普电脑;product.Price 3000;EntryInfo(tracker,修改一项商品数据的名称);db.Product.Add(new Product{Name 鼠标,Price 19,Category 办公用品,});EntryInfo(tracker, 添加一项商品数据);var product2 db.Product.Find(2);db.Product.Remove(product2);EntryInfo(tracker,删除一项商品数据);Console.Read();} }static void EntryInfo(DbChangeTracker tracker,string desc) {Console.WriteLine(\n{0}: ,desc);Console.WriteLine(.PadRight(48, .));IEnumerableDbEntityEntry entries tracker.Entries();foreach (DbEntityEntry entry in entries){Console.WriteLine(变更实体:{0},entry.Entity.GetType().FullName);EntityState state entry.State;Console.WriteLine(状态{0}, state);if (state ! EntityState.Deleted){if (state ! EntityState.Added){PropertyList(entry.GetDatabaseValues(),当前数据库中的副本);PropertyList(entry.OriginalValues,属性值);}if (state ! EntityState.Unchanged){PropertyList(entry.CurrentValues, 变更后的属性值);}Console.WriteLine(//);}} }static void PropertyList(DbPropertyValues values,string desc) {Console.WriteLine({0}:, desc);foreach (string name in values.PropertyNames){Console.WriteLine(\t{0}:{1}, name, values[name]);} } 修改实体部分的运行结果 新增实体部分的运行结果 删除实体部分的运行结果 更新验证异常——DbEntityValidationException 数据进入数据库之前很有可能发生各种更新错误因此必须进行各种验证以确保正确性。当我们执行SaveChanges方法进行底层数据更新操作时EF会根据实体类的属性逐一进行验证以决定是否执行数据的更新操作避免错误数据进入数据库。一旦出现验证不符的数据内容就会产生DbEntityVaildationException异常。 下面通过例子说明新建控制台项目SaveChangesEX并添加如下实体类 [Table(Product)]public class Product{[Key]public int Id { get; set; }[Required]public string Name { get; set; }[Range(100,5000)]public int Price { get; set; }[Range(100,5000)]public int SPrice { get; set; }} 上下文类代码如下图所示 public class SaveChangesEXModel : DbContext{public SaveChangesEXModel(): base(nameSaveChangesEXModel){}public virtual DbSetProduct Product { get; set; }} 首次运行项目在数据库中建立的表结构如下图所示 修改Main函数中的代码如下图所示 static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){try{Product product new Product{Name null,Price -40,SPrice -120,};db.Product.Add(product);int count db.SaveChanges();}catch(Exception ex){Console.WriteLine(\n错误信息{0}\n,ex.Message);}Console.ReadKey();} } 以上代码创建了一个新的Product对象并将其name属性赋值为null 这是无法通过验证的同理Price属性和SPrice属性。 运行效果如下图所示 下面进一步扩展catch子句中的代码 static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){try{Product product new Product{Name null,Price -40,SPrice -120,};db.Product.Add(product);int count db.SaveChanges();}catch(Exception ex){Console.WriteLine(\n错误信息{0}\n,ex.Message);if (ex is DbEntityValidationException){foreach (DbEntityValidationResult validationResult in ((DbEntityValidationException)ex).EntityValidationErrors){foreach (DbValidationError error in validationResult.ValidationErrors){Console.WriteLine(.....{0},error.ErrorMessage);}}}}Console.ReadKey();} } DbEntityValidationException.EntityValidationErrors属性返回与此实体对象有关的验证错误每一个验证错误封装为DbEntityValidationResult 对象最后形成IEnumerableDbEntityValidationResult返回因此我们可以通过foreach循环列举其中所有的DbEntityValidationResult 对象。 每一个实体相关的验证错误进一步封装在DbEntityValidationResult.ValidationErrors属性返回的ICollectionDbVaildationError集合中通过其中的DbValidationError.ValidationErrors可以取出真正的信息。 如果想要同时获取造成这个错误的关键属性。可以调用DbValidationError.PropertyName以获取属性名称。 运行效果如下图所示 上述输出结果中除了原来的信息外同时还列出了每一组属性专属的错误信息这些信息是属性数据注解内置的默认消息正文。如果需要设置ErrorMessage指定输出信息可以修改Product.cs如下所示 [Table(Product)]public class Product{[Key]public int Id { get; set; }[Required(ErrorMessage 必须指定商品名称)]public string Name { get; set; }[Range(100,5000,ErrorMessage 商品价格范围10-500)]public int Price { get; set; }[Range(100,5000,ErrorMessage 商品特价范围10-500)]public int SPrice { get; set; }} 运行效果如下图所示 覆写DbContext.ValidateEntity方法 可以覆写DbContext.ValidateEntity方法自定义验证程序以进一步调整输出验证结果修改上下文类代码如下图所示 public class SaveChangesEXModel : DbContext {public SaveChangesEXModel(): base(nameSaveChangesEXModel){}public virtual DbSetProduct Product { get; set; }protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionaryobject, object items){var list new ListDbValidationError();if (entityEntry.CurrentValues.GetValuestring(Name) null || entityEntry.CurrentValues.GetValuestring(Name).Length 4){list.Add(new DbValidationError(Name, 商品名称必须多于四个字符));}if (entityEntry.CurrentValues.GetValueint(Price) 0){list.Add(new DbValidationError(Price,商品价格不得小于0));}if (entityEntry.CurrentValues.GetValueint(SPrice) 0){list.Add(new DbValidationError(SPrice, 商品特价不得小于0));}if (list.Count() 0){return new DbEntityValidationResult(entityEntry, list);}else{return base.ValidateEntity(entityEntry, items);}} } 再次运行程序会得到如下结果 覆写SaveChange方法  在EF环境下数据变更是最后调用SaveChanges方法将数据正式更新到数据库如果在更新过程中有需要执行的程序代码可以尝试直接在实体模型中覆写这个方法。 我们可以将处理验证异常的相关代码覆写到SaveChange方法中如此一来就不需要每次调用SaveChange时处理相关问题。 修改上下文代码如下图所示 public class SaveChangesEXModel : DbContext{public SaveChangesEXModel(): base(nameSaveChangesEXModel){}public virtual DbSetProduct Product { get; set; }public override int SaveChanges(){try{return base.SaveChanges();}catch (Exception ex){string message ex.Message;if (ex is DbEntityValidationException){message 验证异常\n;foreach (var validationResult in ((DbEntityValidationException)ex).EntityValidationErrors){foreach (var error in validationResult.ValidationErrors){message (...... error.ErrorMessage \n);}}}throw new Exception(message);} }} 修改Main方法中代码如下图所示 static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){try{Product product new Product{Name null,Price -40,SPrice -120,};db.Product.Add(product);int count db.SaveChanges();Console.WriteLine(添加了{0}项数据!, count);}catch(Exception ex){Console.WriteLine(\n错误信息{0}\n, ex.Message);}Console.ReadKey();} } 运行结果如下图所示 SQL语句 EF支持SQL语句以便我们随时进行数据的增删改查操作。示例代码如下图所示 using System.Data.Entity.Infrastructure;static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){string sql SELECT * FROM dbo.Product;DbSqlQueryProduct query db.Product.SqlQuery(sql);ListProduct products query.ToList();Console.WriteLine(商品项数:{0},products.Count());foreach (Product product in products){Console.WriteLine({0}\t售价{1}特价{2},product.Name,product.Price,product.SPrice);}Console.ReadKey();} } 运行结果如下图所示 注意以下几点 1、SQl语句语法必须正确 不然报错。 2、SQl语句得到的属性值个数必须和指定的类型的属性个数相同。比如select NamePrice From Product 这句Sql中只有Name和Price两个属性无法顺利转化成Product对象故会报错。 当查询结果属性个数不同时可以使用如下方法修改Main函数中代码如下图所示 static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){string sql SELECT Name FROM dbo.Product;DbRawSqlQuerystring query db.Database.SqlQuerystring(sql);//此方法Liststring productsName query.ToList();Console.WriteLine(商品项数:{0}, productsName.Count());foreach (string productName in productsName)Console.WriteLine({0}, productName);}Console.ReadKey(); } 如果需要返回多个字段可以预先创建对应的类进行转换如下图所示 public class SProduct{public int Id { get; set; }public string Name { get; set; }public int Price { get; set; }} 修改Main函数中的代码 static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){string sql SELECT Name,Price FROM dbo.Product;DbRawSqlQuerySProduct query db.Database.SqlQuerySProduct(sql);ListSProduct products query.ToList();Console.WriteLine(商品项数:{0}, products.Count());foreach (SProduct product in products){Console.WriteLine({0} ,价格{1}, product.Name,product.Price);}Console.ReadKey();} } 在SQL语句中使用参数 不当的SQL语句很容易遭受黑客的注入攻击我们可以使用参数动态建立所需要的SQL语句。代码如下 static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){SqlParameter P0 new SqlParameter(P0,8);SqlParameter P1 new SqlParameter(P1, %移动%);object[] parameters { P0,P1 };string sql select Id,Name,Price From Product Where Id P0 AND Name LIKE P1 ;DbRawSqlQuerySProduct query db.Database.SqlQuerySProduct(sql, parameters);ListSProduct Products query.ToList();} } 上述SQL语句查找Id大于8并且名字包含“移动”的数据。 执行非查询变更指令——ExecuteSqlCommand  Update、InsertInto、delete等更新操作必须通过ExecuteSqlCommand方法而且不会返回任何数据集。语句如下 int count context.Database.ExecuteSqlCommand(sql) 上述的程序代码返回变更的数据项count 记录了被更新的项数。 using (SaveChangesEXModel db new SaveChangesEXModel()) {string sql UPDATE Product SET SPrice -1 Where Price 100;int count db.Database.ExecuteSqlCommand(sql);Console.WriteLine(更新数据项数:{0},count);Console.ReadKey(); } 同样可以在SQL语句中使用参数 using (SaveChangesEXModel db new SaveChangesEXModel()) {SqlParameter P0 new SqlParameter(P0, -1);SqlParameter P1 new SqlParameter(P1, 100);object[] parameters { P0, P1 };string sql UPDATE Product SET SPrice P0 Where Price P1;int count db.Database.ExecuteSqlCommand(sql,parameters);Console.WriteLine(更新数据项数:{0},count);Console.ReadKey(); } 使用Local查询追踪本地数据集 可以使用DbSet.Local属性返回当前系统本地的数据内容也就是DbContext对象追踪的数据集内容。 参考如下代码 context.Product.Count() context.Product.Local.Count() 第一条会送出SQL语句查询返回数据库中对应的数据表中所储存的记录条数。第二行则是针对本地的DbSet对象读取其中的数据项数(或者记录条数)由于没有执行查询DbContext并没有获取任何数据进行处理因此第二条的值为0. static void Main(string[] args) {using (SaveChangesEXModel db new SaveChangesEXModel()){var count db.Product.Count();Console.WriteLine(数据库中数据的条数{0},count);try{Product product new Product{Name 茶杯,Price 10,SPrice 5,};db.Product.Add(product);Console.WriteLine(本地的数据条数{0}, db.Product.Local.Count);}catch (Exception ex){Console.WriteLine(\n错误信息{0}\n, ex.Message);}Console.ReadKey();} } 运行结果如下图所示 local查询  EF只有真正取出数据内容时才会进行SQL语句的传送而这个过程是EF自动执行的因此不当的设计容易造成重复查询引发严重的性能问题若要避免这种情况可以尝试通过Local获取载入的数据往后对Local数据进行操作以减少SQL查询操作。 通过以下程序代码来说明 using(var context new KTStoreModel) {var products context.product.Where(p p.price 100);Product firstProduct products.First();Console.WriteLine(\n第一项商品数据名称:{0}\n,firstProduct.Name);Console.Writeline(\n所有商品数据列表:\n);foreach(var product in products){Console.WriteLine(Product.Name);}Console.Read() } 上述代码会导致SQL语句执行两次第一次是查询第一项商品数据第二次是查询所有商品数据。 改写代码将其中Where方法的调用调整如下 context.Product.Where(p p.price 100).Load(); var products context.product.local; 第一次直接调用Load方法预先将数据载入DbContext并且通过Local属性的引用取回载入的数据内容并存储于Products变量中。由于直接查询Local属性获取本地数据因此不需要重复执行SQL语句这对于性能的提升会有一定帮助。
http://www.yutouwan.com/news/167195/

相关文章:

  • 网站建设要域名和什么网站策划书预期风险
  • 网站开发的平台网站建设费的会计分录
  • 东莞网站建设(信科分公司)wordpress主题首页显示不全
  • 网站建设法律可行性网页链接中的文件路径分为
  • 在小说网站做责编创建wordpress主题
  • sqlite3做网站数据库东莞网站建设团队全网天下
  • 网页新建站点食品电子商务网站建设规划书
  • 江苏连云港网站设计公司cordova wordpress
  • 功能型类的网站品牌建设ppt
  • 大连响应式网站建设网站建设先进
  • 湖北省建设工程信息网seo薪资
  • html5 网站 优势怎么做网页设计原型
  • 网站链接建设及引流营销简单网页制作视频教程
  • 公司注册网上核名网站华美天一建筑公司网站
  • 企业网站建设哪家快石家庄造价信息网
  • 定制网站成本多少做一个国外网站
  • 网站排行首页怎么做做优化需要发多少个网站
  • php网站开发课程阿里云网站怎么建设
  • 外国网站打开很慢网站宣传的方式
  • 建筑网格化国内seo排名分析主要针对百度
  • 专业做网站的软件食品品牌推广方案
  • 阿里云做的网站怎么备份有什么平台做网站比较好
  • wordpress 网站收录wordpress用qq注册
  • 怎样做企业的网站wordpress 判断是否首页
  • minisite网站案例wordpress安装目录
  • 北京网站建站系统平台广州工商注册查询系统
  • 重庆网站页设计制作个体商户建自己的网站做销售
  • 网站建设制作免费咨询做旅游的网站的需求
  • 旅游景点网站模板大全wordpress 自己做主页
  • 谷歌推广网站怎么做郑州最近新闻事件