EntityFramework 基础的crud操作
根据上一张实体映射的demo学习基础的crud操作
1、增加
BlogDbContext dbContext = new BlogDbContext(); var post = new Post() { PostTitle = "测试添加", BlogUserId = 2, CreateTime = DateTime.Now }; var ce = dbContext.Set<Post>(); ce.Add(post); dbContext.SaveChanges();
2、删除
方法一:
var dbcontext = new BlogDbContext(); var posts = dbcontext.Set<Post>(); Post postModel = posts.Find(2); if (postModel != null) { posts.Remove(postModel); dbcontext.SaveChanges(); }
方法二:
var dbcontext = new BlogDbContext(); var posts = dbcontext.Set<Post>(); Post postModel = posts.Find(2); dbcontext.Entry(postModel).State = EntityState.Deleted; dbcontext.SaveChanges();
3、修改
var dbcontext = new BlogDbContext(); var posts = dbcontext.Set<Post>(); Post postModel = posts.Find(2); if (postModel != null) { postModel.PostTitle = "测试修改"; dbcontext.Entry(postModel).State = System.Data.EntityState.Modified; dbcontext.SaveChanges(); }
上面方法中每次都需要对所有字段进行修改,效率低,而且麻烦,下面介绍修改部分字段
var Post = new Post { PostId = 7, PostTitle = "更新", BlogUserId = 3 }; //将实体附加到对象管理器中 dbcontext.Set<Post>().Attach(Post); //获取到Post的状态实体,可以修改其状态 var setEntry = ((IObjectContextAdapter)dbcontext).ObjectContext.ObjectStateManager.GetObjectStateEntry(Post); //只修改实体的PostTitle属性 setEntry.SetModifiedProperty("PostTitle"); //setEntry.SetModifiedProperty("BlogUserId"); dbcontext.SaveChanges();
4、查询
var dbContext = new BlogDbContext(); IQueryable<Post> Posts = dbContext.Set<Post>(); Posts.ToList();
var result = from i in dbContext.Set<Post>() //使用LINQ查询发帖人id为2的帖子 where i.BlogUserId == 2 select i;
如果查询部门字段可以用如下方法:
var dbContext = new BlogDbContext(); IQueryable<Post> Posts = dbContext.Set<Post>(); var data = Posts.Select(c => new { c.PostTitle, c.BlogUserId }).ToList();
以上是使用EF对数据库实现CRDU,但是在有些时候必须要用sql语句
在数据上下文dbContext的实例中有个Database属性,其中有两组方法.ExecuteSqlCommand()和.SqlQuery()。它们都可以执行SQL语句,只不过.ExecuteSqlCommand()是不返回结果的,只返回受影响的行数,所以.ExecuteSqlCommand()更适合执行创建、更新、删除操作。.SqlQuery()则会返回查询到的结果,并将结果保存在数据实体中,所以更适合执行查询操作
使用.ExecuteSqlCommand()实现创建、更新、删除
1、sql语句添加数据
BlogDbContext dbContext = new BlogDbContext();
string sql = @"insert into [Posts] ([PostTitle],[BlogUserId],[CreateTime])
values (@PostTitle,@BlogUserId,@CreateTime)";
var args = new DbParameter[] {
new SqlParameter { ParameterName = "PostTitle", Value = "EntityFramework"},
new SqlParameter { ParameterName = "BlogUserId", Value=2},
new SqlParameter { ParameterName = "CreateTime", Value=DateTime.Now}
};
int rowCount = dbContext.Database.ExecuteSqlCommand(sql, args);
2、修改
var dbcontext = new BlogDbContext(); var result = dbcontext.Database.ExecuteSqlCommand(@"UPDATE [Posts] SET [PostTitle] ='EntityFramework基础的Crud' WHERE PostId = 3;");
3、删除
var dbcontext = new BlogDbContext(); int result = dbcontext.Database.ExecuteSqlCommand(" delete from Posts where PostId=6 ");
使用.SqlQuery()查询数据
从名字就看的出来.SqlQuery()是用来执行查询的。.SqlQuery()使用前需指定返回值的数据类型,比如查询一条帖子的完整信息,类型就可以指定为Post类型。如果是统计有多少条,返回值是个整数,就以设置为int。
注意:不仅返回值的个数必须与传入类型中属性值的个数相同,而且名称还必须一样,不然会出错。那么如果我只想获取标题和id,那就得单独定义一个类(其中包含一个string类型的PostTitle和int类型的PostId),来保存数据了。
string sqlString = "SELECT [PostId],[PostTitle],[BlogUserId],[CreateTime] FROM [Posts] "; BlogDbContext dbContext = new BlogDbContext(); var data = dbContext.Database.SqlQuery<PostDto>(sqlString).ToList();
使用DbSet<T>下的.SqlQuery()
在每个数据实体集合DbSet<T>下也有一个.SqlQuery(),功能与上面介绍的一样,只不过DbSet<T>下的.SqlQuery()只能返回DbSet<T>中包含的类型。但DbSet<T>下的.SqlQuery()在返回数据的同时还会让数据库上下文(DBModel)跟踪返回数据的状态,如果返回的数据发生了修改,就可以使用.SaveChanges()将结果直接保存回数据库。而.Database.SqlQuery()查出的结果则是做不到的。
string sqlString = "SELECT [PostId],[PostTitle],[BlogUserId],[CreateTime] FROM [Posts] "; BlogDbContext dbContext = new BlogDbContext(); var data = dbContext.Set<Post>().SqlQuery(sqlString).ToList();
EF使用事务
使用TransactionScope类
使用之前引入System.Transactions.dll
BlogDbContext dbContext = new BlogDbContext(); using (var tran = new TransactionScope()) //开启事务 { var post = dbContext.Set<Post>().FirstOrDefault(s => s.PostTitle == "EntityFramework"); dbContext.Set<Post>().Remove(post); //删除 dbContext.SaveChanges(); tran.Complete(); //必须调用.Complete(),不然数据不会保存 } //出了using代码块如果还没调用Complete(),所有操作就会自动回滚