EF框架step by step(5)—处理实体简单属性
EF框架会对实体进行跟踪,对实体的每个属性当前值和原始值及其状态进行跟踪,记录。当前值是指实体属性当前的被赋予的值,而原始值是指实体最初从数据库读取或者附加到DbContext时的值。
先通过简单的代码演示一下如何获取这两个值,仍采用上彷文章的案例,多余代码不在展示
数据库内容如下图示
简单获取当前值,初始值
using (BlogDbContext db = new BlogDbContext())
{
BlogUser blogUser = db.BlogUsers.Find(4);
///通过db.Entry(blogUser).Property获取值,参数可以为Lamada表达式,也可以是字符串
///通过Lambda表达式获取当前值,用Lamada表达式时,返回值为强类型,即返回当前属性的类型
///而用字符串做为参数时,返回值为object
string currentName= db.Entry(blogUser)
.Property(user => user.BlogName).CurrentValue;
//object currentObj= db.Entry(blogUser).Property("BlogName").CurrentValue;
Console.WriteLine("当前值:{0}",currentName);
///获取原始值
string orgName = db.Entry(blogUser).Property(user => user.BlogName).OriginalValue;
///string orgName = db.Entry(blogUser).Property("BlogName")
/// .OriginalValue.ToString();
Console.WriteLine("原始值:{0}",orgName);
//修改对象的值
blogUser.BlogName = "宁采臣";
//db.Entry(blogUser).Property(u => u.BlogName).CurrentValue = "宁采臣";
Console.WriteLine("修改后的值为:{0}",blogUser.BlogName);
Console.WriteLine("修改后,再次获取当前值与原始值");
currentName = db.Entry(blogUser).Property(u => u.BlogName).CurrentValue;
orgName = db.Entry(blogUser).Property("BlogName").OriginalValue.ToString();
Console.WriteLine("当前值:{0}", currentName);
Console.WriteLine("原始值:{0}", orgName);
}
运行结果如图:
监控值是否修改:当属性值被改变后,DbContext会自动监测到,可以通过IsModified属性获得。
BlogUser blogUser = db.BlogUsers.Find(4);
///输出 False
Console.WriteLine(db.Entry(blogUser).Property(user => user.BlogName).IsModified);
blogUser.BlogName = "宁采臣";
///输出 True
Console.WriteLine(db.Entry(blogUser).Property(user => user.BlogName).IsModified);
关闭属性修改监测 如果不想让DbContext自动监测,可以设置
db.Configuration.AutoDetectChangesEnabled = false;
强制设置某个属性被更改
db.Entry(blogUser).Property(user => user.BlogName).IsModified = true;
跟踪DbContext中不存在的实体
///新构造一个实体对象
BlogUser newBlogUser = new BlogUser() { BlogName = "Jack" };
///获取其实属性值
var currentName= db.Entry(newBlogUser).Property(user => user.BlogName).CurrentValue;///返回Jack
获取所有属性值,包括当前值,原始值以及数据库里保存的值
BlogUser blogUser = db.BlogUsers.Find(4);
blogUser.BlogName = "宁采臣";
///EF框架直接执行sql语句,更数数据库,不需要调用db.SaveChanges()
db.Database.ExecuteSqlCommand("update blogusers set blogName='Jack' where BlogUserId=4");
Console.WriteLine("当前值");
PrintValues(db.Entry(blogUser).CurrentValues);
Console.WriteLine("原始值");
PrintValues(db.Entry(blogUser).OriginalValues);
Console.WriteLine("数据库值");
PrintValues(db.Entry(blogUser).GetDatabaseValues());
private static void PrintValues(DbPropertyValues values)
{
foreach (var propertyName in values.PropertyNames)
{
Console.WriteLine("{0}={1}",propertyName, values[propertyName]);
}
}
运行结果如下:
这种检测方法,在多用户,允许并发编辑时,可以偿试使用。
用其它对象为当前对象属性赋值
BlogUser blogUser = new BlogUser() { BlogUserId = 1, BlogName = "燕赤霞" };
db.BlogUsers.Attach(blogUser);
var newUser1 = new BlogUser() { BlogUserId = 1, BlogName = "宁采臣" };
var newUser2 = new BlogUserDTO() { Id = 2, BlogName = "黑山老妖" };
var entry = db.Entry(blogUser);
entry.CurrentValues.SetValues(newUser1);
entry.OriginalValues.SetValues(newUser2);
PrintValues(entry.CurrentValues);
PrintValues(entry.OriginalValues);
public class BlogUserDTO
{
public int Id { get; set; }
public string BlogName { get; set; }
}
用Dictionary 为对象属性赋值
BlogUser blogUser = db.BlogUsers.Find(4);
Dictionary<string, string> setValues = new Dictionary<string, string>()
{
{"BlogName","宁采臣"}
};
PrintValues(db.Entry(blogUser).CurrentValues);
foreach (var propertyName in setValues.Keys)
{
db.Entry(blogUser).CurrentValues[propertyName] = setValues[propertyName];
}
PrintValues(db.Entry(blogUser).CurrentValues);
clone一个对象,包括原始值或者当前值,或者当前数据库内保存值
var blogUser = db.BlogUsers.Find(4);
var clonedBlogUser = db.Entry(blogUser).GetDatabaseValues().ToObject() as BlogUser;
Console.WriteLine((clonedBlogUser.BlogName));