如何使用LINQ to Entities更新现有对象的属性?

3
LINQ to Entities 允许这样做:
context.User.Select(u => new Person
{
    Name = u.Name,
    Parent = u.Parent.Name
});

我只需要一个大型“User”表的两个属性,并使用“Select”方法创建一个“Person”对象,以便进行一些处理。问题是我经常这样做(比如每秒两次),这会影响垃圾回收器(GC)。
因此,我决定池化“Person”对象,但我不知道如何使用LINQ更新现有对象。我可以像上面那样将其作为匿名方法获取,然后将其属性分配给depooled对象,然后可以返回depooled实例,这至少会使匿名实例在较低的GC代中消失,但是...
我真的更喜欢这样:
context.User.Select(u => People.Take(u.Name, u.Parent.Name))

这将抛出一个 NotSupportedException 异常。

  • 我能使用 Entity Framework 更新现有对象的值吗?
  • 如果可以,如何操作?
  • 如果不行,我有什么替代方案?
2个回答

2
我能使用Entity Framework更新现有对象的值吗?
不行 - Select方法用于投影而非更新 - 您正在执行的是正确的方法。或者,您可能会发现将您的Person更改为结构体更加高效,因为它消耗更少的内存。
我认为您需要更详细地阐述"它伤害了GC"更新 看起来Linq to Entities不支持在struct上进行投影(对我来说似乎是一种限制) - 那么最好的方法就是仅投影到匿名类型,然后您可以使用池化机制将结果映射到您的Person类。
var users = (from u in context.User
            select new {
                Name = u.Name,
                Parent = u.Parent.Name
            }).ToList().Select(u => People.Take(u.Name, u.Parent));

其次,结构体是个好主意,但我不想让它一遍又一遍地被复制。如果我使用结构体来选择项目,但将其属性分配给一个池化类,会有什么好处吗?我想结构体在方法返回后会被清理,除非我将其分配给全局字段,对吧?最后,我在很多地方都使用那个Person实例,所以在我使用完它之后(没有引用),它不会立即被清理,这在我的情况下会导致内存问题 - 这就是我所说的“它伤害了GC”。我会尝试结构体的想法,再次感谢您。 - Şafak Gür
我觉得我在查询方面的第一点可能是错的(请参阅更新内容),因为查询不知道类型。如果我使用结构来选择项目,但将其属性分配给池化类,这样做有用吗?这肯定比每条记录都创建新的“Person”实例更有效率。"我在很多地方使用了那个“Person”实例"——它是一个单例类吗? - James
不,它是一个拥有相当长寿命的常规类,我每秒钟创建数十个,这就是为什么池化它们而不是等待它们被收集似乎是正确的做法。我会尝试结构体的方法,并且很可能接受这个答案,再次感谢。 - Şafak Gür
啊,好的,如果你发现自己正在创建大量的类并且它们的设置很昂贵,那么池化将是正确的选择 - 这可能是查看结构体的另一个原因。不过,对于你的池化,你如何知道对象不再使用?你只是将属性设置为null吗? - James
是的,这对我来说似乎也是一个毫无意义的限制。而且我想我可以使用匿名对象,因为它的引用将在方法结束时被删除,并且希望它会在下一次GC周期中被收集。我会尝试一下,谢谢。由于我们知道不能使用结构体,您能更新一下您的答案吗? - Şafak Gür
显示剩余3条评论

1

你不能只从数据库中提取对象的几个属性。如果你想要更新它,你必须获取完整的对象,更新它,然后保存更改。

但是如果你真的需要更新几个字段而不想移动整个对象,你可以使用context对象的ExecuteStoredCommand方法(MySQL示例):

    context.ExecuteStoredCommand("UPDATE table1 SET field1 = @value1 WHERE field2 = @value2", new MySqlParameter("@value1", 1), new MySqlParameter("@value2", 2))

这需要您编写一些SQL代码,但可以节省您的时间,因为您不需要担心打开连接、创建命令和其他需要使用常规连接器的事情。


谢谢,但我不需要更新那些字段,我只需要获取它们。 - Şafak Gür

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接