Linq查询
无论是什么查询----一定是生成Sql语句;数据库只认识Sql语句; 如何查看Sql语句: 1.SqlProfiler,可以监听到数据库执行的所有SQL语句 2.通过EF6日志打印数据Sql语句
using (SunDbContext dbContext = new SunDbContext())
{
dbContext.Database.Log += s => Console.WriteLine($"sql:{s}");
{
var idlist = new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17 };
var list = dbContext.SysUsers.Where(u => idlist.Contains(u.Id));
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = from u in dbContext.SysUsers
where new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14 }.Contains(u.Id)
select u;
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = dbContext.SysUsers.Where(u => new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 18, 19, 20, 21, 22, 23 }.Contains(u.Id))
.OrderBy(u => u.Id)
.Select(u => new
{
Name = u.Name,
Pwd = u.Password
}).Skip(3).Take(5);
foreach (var user in list)
{
Console.WriteLine(user.Pwd);
}
}
{
var list = (from u in dbContext.SysUsers
where new int[] { 1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14 }.Contains(u.Id)
orderby u.Id
select new
{
Name = u.Name,
Pwd = u.Password
}).Skip(3).Take(5);
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
}
{
var list = dbContext.SysUsers.Where(u => u.Name.StartsWith("小")
&& u.Name.EndsWith("村长"))
.Where(u => u.Name.EndsWith("长"))
.Where(u => u.Name.Contains("名村"))
.Where(u => u.Name.Length < 5)
.OrderBy(u => u.Id);
foreach (var user in list)
{
Console.WriteLine(user.Name);
}
var list1 = from u in dbContext.SysUsers
where u.Name.StartsWith("小")
&& u.Name.EndsWith("村长")
where u.Name.EndsWith("长")
select new { Name = u.Name, pwd = u.Password };
foreach (var user in list1)
{
Console.WriteLine(user.Name);
}
}
{
var list = (from u in dbContext.SysUsers
join c in dbContext.Companies on u.CompanyId equals c.Id
where new int[] { 1, 2, 3, 4, 6, 7, 10 }.Contains(u.Id)
select new
{
Name = u.Name,
Pwd = u.Password,
CompanyName = c.Name
}).OrderBy(u=>u.CompanyName).Skip(3).Take(5);
foreach (var user in list)
{
Console.WriteLine("{0} {1}", user.Name, user.Pwd);
}
}
}
SQL查询
那都是生成Sql语句,如果我自己来一条Sql语句呢?咋玩? dbContext.Database.SqlQuery< SysUser>(sql, parameter)
事务执行: dbContext.Database.BeginTransaction() trans.Commit()
using (SunDbContext dbContext = new SunDbContext())
{
{
DbContextTransaction trans = null;
try
{
trans = dbContext.Database.BeginTransaction();
string sql = "Update [SysUser] Set Name='小新' WHERE Id=@Id";
SqlParameter parameter = new SqlParameter("@Id", 3);
dbContext.Database.ExecuteSqlCommand(sql, parameter);
trans.Commit();
}
catch (Exception ex)
{
if (trans != null)
trans.Rollback();
throw ex;
}
finally
{
trans.Dispose();
}
}
{
DbContextTransaction trans = null;
try
{
trans = dbContext.Database.BeginTransaction();
string sql = "SELECT * FROM [SysUser] WHERE Id=@Id";
SqlParameter parameter = new SqlParameter("@Id", 3);
List<SysUser> userList = dbContext.Database.SqlQuery<SysUser>(sql, parameter).ToList<SysUser>();
trans.Commit();
}
catch (Exception ex)
{
if (trans != null)
trans.Rollback();
throw ex;
}
finally
{
trans.Dispose();
}
}
}
EntityState状态跟踪
一次SaveChanges 就把在Context中的所有操作都提交到数据库中去了; SaveChange就是以Context为维度的; 要提交到数据库中的对象和Context一定存在某种关系;----就是对象是否给Context跟踪;状态;
using (SunDbContext context = new SunDbContext())
{
SysUser userNew = new SysUser()
{
Name = "7z",
Password = "12356789",
Status = 1,
Phone = "18672713698",
Mobile = "18664876671",
Address = "xxx市",
Email = "18672713698@qq.com",
QQ = 75379953,
WeChat = "xxxx",
Sex = 1,
CreateTime = DateTime.Now,
CompanyId = 4,
LastLoginTime = null,
LastModifyTime = DateTime.Now
};
Company company = new Company()
{
Name = "腾讯有限公司",
LastModifierId = 1,
CreateTime = DateTime.Now,
CreatorId = 1,
LastModifyTime = DateTime.Now
};
context.Companies.Add(company);
context.SysUsers.Add(userNew);
context.SaveChanges();
userNew.Name = "天气老师";
context.SaveChanges();
context.SysUsers.Remove(userNew);
context.SaveChanges();
}
Context.Entry< User>(userNew).State :获取实体的状态
Detached: 和Context 完全没有任何关系,不受Context跟踪 Unchanged:受Context跟踪,但是没有做任何操作 Added:受Context 跟踪,SaveChange就添加到数据库 Deleted:受Context跟踪,SaveChange就删除数据库数据 Modified:受Context跟踪,SaveChange就修改数据库
SysUser userNew = new SysUser()
{
Name = "7z",
Password = "12356789",
Status = 1,
Phone = "18672713698",
Mobile = "18664876671",
Address = "xxx市",
Email = "18672713698@qq.com",
QQ = 75379953,
WeChat = "xxxx",
Sex = 1,
CreateTime = DateTime.Now,
CompanyId = 4,
LastLoginTime = null,
LastModifyTime = DateTime.Now
};
using (SunDbContext context = new SunDbContext())
{
Console.WriteLine(context.Entry<SysUser>(userNew).State);
userNew.Name += "abcd";
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
context.SysUsers.Add(userNew);
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
context.SaveChanges();
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
userNew.Name = "小星星老师";
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
context.SaveChanges();
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
context.SysUsers.Remove(userNew);
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
context.SaveChanges();
Console.WriteLine(context.Entry<SysUser>(userNew).State);
Console.WriteLine("*******************************************");
}
}
SaveChanges是以context为维度,如果监听到任何数据的变化;然后会一次性的保存到数据库去,而且会开启事务!
那如果是这样的话,岂不是每一次更新都需要从数据库里查询一次? 大部分情况下是这样,先查询,再修改,为了保证实体受Context监管! 也可以有其他的方案:Context.实体名称.Attach() 接受Context监管!
SysUser userNew1 = new SysUser()
{
Name = "ABCDEFG",
Password = "12356789",
Status = 1,
Phone = "18672713698",
Mobile = "18664876671",
Address = "xxx市",
Email = "18672713698@qq.com",
QQ = 75379953,
WeChat = "xxxx",
Sex = 1,
CreateTime = DateTime.Now,
CompanyId = 4,
LastLoginTime = null,
LastModifyTime = DateTime.Now
};
using (SunDbContext context = new SunDbContext())
{
context.SysUsers.Attach(userNew1);
Console.WriteLine(context.Entry<SysUser>(userNew1).State);
context.SaveChanges();
Console.WriteLine(context.Entry<SysUser>(userNew1).State);
userNew1.Name += "123465";
context.SaveChanges();
Console.WriteLine(context.Entry<SysUser>(userNew1).State);
}
SysUser sysUser2 = null;
using (SunDbContext context = new SunDbContext())
{
SysUser user = context.SysUsers.Find(100026);
Console.WriteLine(context.Entry<SysUser>(user).State);
sysUser2 = user.clone();
Console.WriteLine(context.Entry<SysUser>(sysUser2).State);
context.SysUsers.Attach(sysUser2);
Console.WriteLine(context.Entry<SysUser>(sysUser2).State);
sysUser2.Name += "123456987";
Console.WriteLine(context.Entry<SysUser>(sysUser2).State);
context.SaveChanges();
}
状态跟踪有成本:在内存中Clone一个对象,只要是被Context跟踪上的;每一次修改,都会和内存中的克隆的对象做比较;比较之后的结果就是新状态;—也会影响我们的性能;
取消对象的状态跟踪:AsNoTracking() 方法会直接切断Context跟踪;可以提高性能!
{
using (SunDbContext context = new SunDbContext())
{
SysUser user = context.SysUsers.Find(100026);
Console.WriteLine(context.Entry<SysUser>(user).State);
var user1 = context.SysUsers.AsNoTracking().FirstOrDefault(u => u.Id == 100026);
Console.WriteLine(context.Entry<SysUser>(user1).State);
var userQuery = context.SysUsers.Where(u => u.Id == 100026).ToList();
Console.WriteLine(context.Entry<SysUser>(userQuery.First()).State);
}
}
EF中的缓存提升效率: Find查询默认是优先从内存中去查找,如果内存没有,就再去数据库查找,可以提高性能; 建议:大家尽量的使用Find查询
{
using (SunDbContext context = new SunDbContext())
{
var userlist = context.SysUsers.Where(u => u.Id > 100025).ToList();
Console.WriteLine("*******************************************************");
SysUser user = context.SysUsers.Find(100026);
Console.WriteLine("*******************************************************");
SysUser user1 = context.SysUsers.FirstOrDefault(u => u.Id == 100026);
}
using (SunDbContext context = new SunDbContext())
{
SysUser user = context.SysUsers.Find(100026);
}
}
那如何更新全部字段0呢? context.Entry< User>(user).State = EntityState.Modified;//全字段更新 那如何选择性的更新字段呢? context.Entry< User>(user5).Property(“Name”).IsModified = true;
SysUser updateuser = null;
using (SunDbContextcontext = new SunDbContext())
{
SysUser user = context.SysUsers.Find(100026);
user.Name = "tengxunketang";
context.SaveChanges();
var upUser = context.SysUsers.Find(updateuser.Id);
context.Entry<SysUser>(updateuser).State = EntityState.Modified;
context.Entry<SysUser>(updateuser).Property("Name").IsModified = true;
}
多个新增、修改 savechange()相当于是在同一个事务中进行,某一条语句失败事务就无法提交。
|