Linq 整体更新一行数据的问题

richie8398 2012-01-09 10:10:44

abc _entity = db.abc.SingleOrDefault(e => e.id == 123);//id是主键,自增列
_entity = entity;
db.SubmitChanges();


为什么整体修改一行记录总是不能成功呢。如果换成每个属性重新赋值的话,就没问题。请大侠帮忙解决一下,很急。
...全文
3237 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
tptptp00 2012-03-02
  • 打赏
  • 举报
回复
public void ConvertPro<TSource>(TSource model1, TSource model2)
{
PropertyInfo[] properties = model1.GetType().GetProperties();
Type t = model2.GetType();
foreach (var item in properties)
{
t.InvokeMember(item.Name, BindingFlags.SetProperty, null, model2, new object[] { item.GetValue(model1, null) });
}
}


ktei2008 2012-02-28
  • 打赏
  • 举报
回复
再补充一点:
虽然你有_entity = entity,但很可能你的entity已经脱离了“生出”这个entity的DataContext的“监控”,而另一个DataContext对此entity是完全陌生的,它不知道什么属性改变了,什么没改变,这时候如果你去Update(_entity),即Update(entity),是无效的。
ktei2008 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 richie8398 的回复:]
C# code

abc _entity = db.abc.SingleOrDefault(e => e.id == 123);//id是主键,自增列
_entity = entity;
db.SubmitChanges();



为什么整体修改一行记录总是不能成功呢。如果换成每个属性重新赋值的话,就没问题。请大侠帮忙解决一下,很急。
[/Quote]

如果你肯但凡看一下EF的官方实例,你会发现没有任何一段代码是写成这样的。
DataContext是比较傻的:一旦你用它读出一个entity,然后如果你又将其Close,那么这个entity就被称作detached,也就是说此实体脱离了DataContext的监控,使得DataContext无法跟踪此实体的变化。所以,要么你就保持DataContext一直打开(不推荐),要么就在Update的时候再将实体attach回DataContext,然后再SaveChanges;我从网上找了一个小例子给你,不要纠结于那个T,那只是个范类而已。


public void UpdateObject(T obj)
{
using (var context = new MyDataContext())
{
context.CreateObjectSet<T>().Attach(obj);
context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
context.SaveChanges();
}
}

sugarbelle 2012-01-11
  • 打赏
  • 举报
回复
abc entity = db.abc.SingleOrDefault(e => e.id == Convert.ToInt32(Request.QueryString["id"]));
entity.cname = name;

SingleOrDefault 返回的可能是空.
那么下一条
entity.cname = name;
就是错的.因为entity没有new.
richie8398 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 claymore1114 的回复:]
你这两行的代码 赋值的意思 要弄清楚,基础,内存分布问题,跟VS 哪有关系。
//在托管堆一个变量_entity 指向db.abc.SingleOrDefault(e => e.id == entity.id);
abc _entity = db.abc.SingleOrDefault(e => e.id == entity.id);
//变量_entity 指向entity,不再指向原来那……
[/Quote]

_entity是从数据库中查出的
entity是内存中已经改过的新的实体
_entity=entity是在内存中更新从数据库查出的记录,之前好多项目一直这么写的,没有问题。只是现在发现这样不管用了。
claymore1114 2012-01-09
  • 打赏
  • 举报
回复
你这两行的代码 赋值的意思 要弄清楚,基础,内存分布问题,跟VS 哪有关系。
//在托管堆一个变量_entity 指向db.abc.SingleOrDefault(e => e.id == entity.id);
abc _entity = db.abc.SingleOrDefault(e => e.id == entity.id);
//变量_entity 指向entity,不再指向原来那个了。
//db.abc.SingleOrDefault(e => e.id == entity.id); 和_entity 并没有发生关系
_entity = entity;
// 没有改变,你保存啥?
db.SubmitChanges();
q107770540 2012-01-09
  • 打赏
  • 举报
回复
这个可以肯定的说,跟VS版本没有关系
richie8398 2012-01-09
  • 打赏
  • 举报
回复
源代码少贴了点


DataClasses1DataContext db = new DataClasses1DataContext();

//页面处理新的对象
string name = txtName.Text.Trim();
abc entity = db.abc.SingleOrDefault(e => e.id == Convert.ToInt32(Request.QueryString["id"]));
entity.cname = name;
Update(entity);


//数据访问层处理Update方法
public void Update(abc entity)
{
abc _entity = db.abc.SingleOrDefault(e => e.id == entity.id);
_entity = entity;
db.SubmitChanges();
}


修改时,我不指定修改了哪些字段,而是直接修改整个实体(entity),然后提交数据库修改。因为如果字段很多的话,不想每个字段都重新赋值。(我在vs2008的项目中都是这么做的,而且没问题,vs2010就不行了,不知道是否跟vs版本有关系呀。)
hztltgg 2012-01-09
  • 打赏
  • 举报
回复
entity哪儿来的?为什么不直接修改?
jiuhexuan 2012-01-09
  • 打赏
  • 举报
回复
确保entity
各字段与_entity一致,只是修改某些
richie8398 2012-01-09
  • 打赏
  • 举报
回复
对了,补充一下:之前我用的vs2008都是这么用的,没出现上述问题,现在改用vs2010了,才有这个问题。
richie8398 2012-01-09
  • 打赏
  • 举报
回复
确实没有用到反射,因为我也参与了框架的设计。所以,我肯定跟现在的写法一样。晕了,谁能帮我解决一下
hztltgg 2012-01-09
  • 打赏
  • 举报
回复
要不你以前的项目重载了=运算符,通过反射全部自动赋值了一遍
richie8398 2012-01-09
  • 打赏
  • 举报
回复
晕,之前一直用的linq的框架,更新都是这么写的。
hztltgg 2012-01-09
  • 打赏
  • 举报
回复
之前好多项目一直这么写的,没有问题。只是现在发现这样不管用了。
=============

以前的项目悲剧了,要不就是以前你们用了另外一个类似的框架,但不是你现在用的这个。
claymore1114 2012-01-09
  • 打赏
  • 举报
回复
哎! 怎么说不通呢
_entity之前的假设为A
_entity赋值为entity(假设B)之后,_entity里面的值当然是entity(你修改后的),因为它指向entity,操作它的属性后,仍然是在操作B区。
_entity没有指向A了,也不能操作A,_entity你再怎么折腾,跟A没关系了。

而db.SubmitChanges(); 是操作A的,不是操作B的。
richie8398 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 claymore1114 的回复:]
我的理解
堆栈 _entity 变量 一开始指向
托管堆(假设内存A) db.abc.SingleOrDefault(e => e.id == entity.id);
经过赋值
堆栈 _entity 变量 指向 托管堆(假设内存B) entity
A和B 是一样的?
db.SubmitChanges();执行保存的还是A, A并没有发生变化。
[/Quote]

_entity和entity是不一样的,entity是经过修改后的(比如:里面的name值变化了)。所以_entity=entity,这样的结果是_entity也变成了经过修改后的实体。我觉得你还是没有看明白我上面贴的代码。
claymore1114 2012-01-09
  • 打赏
  • 举报
回复
我的理解
堆栈 _entity 变量 一开始指向
托管堆(假设内存A) db.abc.SingleOrDefault(e => e.id == entity.id);
经过赋值
堆栈 _entity 变量 指向 托管堆(假设内存B) entity
A和B 是一样的?
db.SubmitChanges();执行保存的还是A, A并没有发生变化。
richie8398 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 claymore1114 的回复:]
引用 7 楼 richie8398 的回复:
引用 6 楼 claymore1114 的回复:
你这两行的代码 赋值的意思 要弄清楚,基础,内存分布问题,跟VS 哪有关系。
//在托管堆一个变量_entity 指向db.abc.SingleOrDefault(e => e.id == entity.id);
abc _entity = db.abc.SingleOrDefault(e =>……
[/Quote]

这个我敢肯定一样,因为好多项目都是这样写的。
claymore1114 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 richie8398 的回复:]
引用 6 楼 claymore1114 的回复:
你这两行的代码 赋值的意思 要弄清楚,基础,内存分布问题,跟VS 哪有关系。
//在托管堆一个变量_entity 指向db.abc.SingleOrDefault(e => e.id == entity.id);
abc _entity = db.abc.SingleOrDefault(e => e.id == entity.id);
//……
[/Quote]
你以前的也肯定不行,行的话,那肯定跟这个不一样。 哈哈 坐等 专家来解释。

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧