本文目录EF对单个实体的增查改删增加单个实体查询单个实体修改单个实体删除单个实体EF里主从表关联数据的各种增删改查增加(增加从表数据、增加主从表数据)查询(根据主表找从表数据、根据从表找主表数据)修改(修改从表的外键)删除(删除主从表关系、删除主表数据、删除主从表数据、修改从表数 ...
本文目录
还有一种不加载实体到内存就可以删除实体的简单方法,用EF直接执行sql:
/// <summary> /// 删除单个实体ExecuteSqlCommand /// </summary> private static void DeleteWineGlassBayExecuteSqlCommand() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { context.Database.ExecuteSqlCommand("delete from baga.Locations where LocationName = 'Hawaii'"); } }
可见,都不需要调用上下文的SaveChanges方法了,因为是直接执行sql,所有并不需要EF跟踪任何状态然后提交到数据库。
删除主表数据同时删除相关联的从表数据(级联删除)
/// <summary> /// 显示加载从表数据 /// </summary> private static void DeleteGrandCanyonLoadRelateData() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { var canyon = (from d in context.Destinations where d.Name == "Grand Canyon" select d).Single(); context.Entry(canyon).Collection(d => d.Lodgings).Load(); //显示加载 //不调用Load,也可以先调用Query方法,在内存中执行需要的操作再把结果集加载到内存中,效率!比如: //context.Entry(canyon).Collection(d => d.Lodgings).Query().Where(l => l.Name.Contains("Hotel")).Load(); context.Destinations.Remove(canyon); context.SaveChanges(); } }
因为Destination类和Lodging类已经设置好了级联删除,所以直接找到主键删除即可,相关联的从表数据由数据库自动删除:
/// <summary> /// 级联删除:不加载从表数据(数据库里必须设置是级联删除) /// </summary> private static void DeleteGrandCanyonWithoutLoadRelateData() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { var canyon = (from d in context.Destinations where d.Name == "Grand Canyon" select d).Single(); context.Destinations.Remove(canyon); context.SaveChanges(); } }
删除主表数据同时删除相关联的从表数据(非级联删除)
标注每个从表的数据为删除状态,然后调用数据库上下文的SaveChanges方法:
/// <summary> /// 普通删除:删除主表数据,同时标注从表数据为删除状态(数据库关闭了级联删除的情况,可以手动去数据库的外键关系修改,也可以Fluent API配置关闭级联删除) /// </summary> private static void DeleteGrandCanyonAndMarkChildEntitiesDeletion() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { var canyon = (from d in context.Destinations where d.Name == "Grand Canyon" select d).Single(); foreach (var lodging in canyon.Lodgings.ToList()) { context.Lodgings.Remove(lodging); //先标记相关的从表数据为删除状态 } context.Destinations.Remove(canyon); //再标记主表数据为删除装填 context.SaveChanges(); //执行上面的所有标记 } }
删除主表数据同时修改相关联的从表数据指向另一个主表实体:
/// <summary> /// 普通删除:删除主表数据,同时设置从表数据指向另一个主键(数据库默认打开关闭级联删除都可以) /// </summary> private static void DeleteGrandCanyonAndChangeChildEntitiesPrimaryKey() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { //找到要删除的主表数据 var canyon = (from d in context.Destinations where d.Name == "Grand Canyon" select d).Single(); //找到和主表数据相关的从表数据并修改其主键值,让这些相关的从表数据指向另一个存在的主表数据 var hawaii = context.Destinations.Find(2); //hawaii此时在数据库的主键是2(find方法生成的sql稍复杂,建议使用下面的普通写法) //var hawaii = (from d in context.Destinations // where d.DestinationId == 2 // select d).Single(); foreach (var lodging in canyon.Lodgings.ToList()) { lodging.Destination = hawaii; } //最后删除主表数据,可以此时只是单独的删除主表数据,它已经没有了相关的从表数据了 context.Destinations.Remove(canyon); context.SaveChanges(); } }
补充内容:以上所有演示我们调用SaveChanges都是提交一个更改,我们试着提交多个操作:
/// <summary> /// 一次提交多个修改 /// </summary> private static void MakeMultipleChanges() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { var niagaraFalls = new DbContexts.Model.Destination { Name = "Niagara Falls", Country = "USA" }; context.Destinations.Add(niagaraFalls); var get='_blank'>wineGlassBay = (from d in context.Destinations where d.Name == "Wine Glass Bay" select d).Single(); wineGlassBay.Description = "Picturesque bay with beaches"; context.SaveChanges(); } }
增加一个Destinations表对象,又修改了一个对象,跟踪下sql发现很明确的是一条insert,一条update的sql。SaveChanges也是一个事务,如果一个不成功,那么所有都提交不成功。
仔细看上面的DbSet.Add方法可知,DbSet.Add方法返回的对象就是我们添加的实体对象,上面的Add方法返回的就是DbContexts.Model.Destination。这个给我们编码提供了很好的便利性,我们看一个方法:
/// <summary> /// 有就查询,没有就添加并查询 /// </summary> private static void FindOrAddPerson() { using (var context = new DbContexts.DataAccess.BreakAwayContext()) { var ssn = 123456789; var person = context.People.Find(ssn) ?? context.People.Add(new DbContexts.Model.Person { SocialSecurityNumber = ssn, FirstName = "Phelps", LastName = "Michael" }); Console.WriteLine(person.FirstName); } }
??表示前者如果为null就使用后者。很明显,库里不存在ssn为123456789的人,那么程序添加一个新的ssn为123456789的人,添加完毕,这个person对象就是我们刚调用Add方法添加的person。这里并没有调用SaveChanges方法,如果调用SaveChanges方法通过调用person.PersonId还可以获取自增长的主键id。
原标题:EF里单个实体的增查改删以及主从表关联数据的各种增删 改查
关键词:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。