代码改变世界

EF框架step by step(5)—处理实体简单属性

2011-05-09 15:05  杨延成  阅读(8556)  评论(8编辑  收藏  举报

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