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));