【问题标题】:How to update an existing object's properties using LINQ to Entities?如何使用 LINQ to Entities 更新现有对象的属性?
【发布时间】:2012-11-03 08:23:23
【问题描述】:

LINQ to Entities 允许这样做:

context.User.Select(u => new Person
{
    Name = u.Name,
    Parent = u.Parent.Name
});

我只需要一个大的User 表的两个属性,我使用Select 方法来创建一个Person 对象,这样我就可以对它进行一些处理。问题是我经常这样做(比如每秒两次),这会伤害GC

所以我决定合并Person 对象,但我不知道如何使用 LINQ to Entities 更新现有对象。我可以像上面一样将它作为匿名方法获取,然后将其属性分配给我猜想的解池对象,然后我可以返回解池实例,这至少会使匿名实例在 GC 的较低代中消失。 ..

我真的更喜欢这样的东西:

context.User.Select(u => People.Take(u.Name, u.Parent.Name))

这会引发NotSupportedException

  • 我可以使用实体框架来更新现有对象的值吗?
  • 如果是,怎么做?
  • 如果没有,我还有什么选择?

【问题讨论】:

    标签: c# .net entity-framework linq-to-entities garbage-collection


    【解决方案1】:

    我可以使用实体框架来更新现有对象的值吗?

    否 - Select 方法用于 projection 不更新 - 您所做的是正确的方法。或者,您可能会发现将 Person class 更改为 struct 更有效,因为它消耗的内存更少。

    我认为您需要详细说明“它伤害了GC

    更新

    Linq to Entities 似乎不支持投影到 struct 上(对我来说似乎是一个限制) - 最好的方法是只投影到匿名类型,然后您可以将结果映射到您的 @ 987654325@ 类使用您的池化机制,例如

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

    【讨论】:

    • 感谢您的回答,但我有点困惑。首先,SQL 表达式也不知道 Person 类的属性,但 EF 可以将结果分配给新对象的属性,这意味着它基本上是一个一个地分配属性。为什么它不能对现有对象执行此操作,而它可以对新实例执行相同操作?
    • 其次,struct 是个好主意,但我不希望它被一遍又一遍地复制。如果我使用结构来选择项目但将其属性分配给池类,它会有什么好处吗?我想结构会在方法返回后被清理,除非我将它分配给全局字段,对吧?最后;我在很多地方都使用了那个 Person 实例,所以在我用完它(没有留下任何引用)后它不会被清理一段时间,这会在我的场景中导致内存问题——这就是我的意思“它伤害了GC”。我会试试 struct 的想法,再次感谢。
    • 关于不知道类型的查询,我认为第一点是错误的(请参阅更新)。 “如果我使用结构来选择项目但将其属性分配给池类,它会有什么好处吗?” - 它肯定比为每条记录创建 Person 的新实例更有效,比如你的做自动取款机。 “我在很多地方都使用那个 Person 实例” - 它是一个单例类吗?
    • 不,这是一个生命周期相当长的常规课程,我每秒创建几十个,这就是为什么将它们汇集而不是等待它们被收集似乎是正确的做法.我会尝试 struct 方法并最有可能接受这个答案,再次感谢。
    • 啊,好吧,如果您发现自己创建了 很多 类并且它们的设置成本很高,那么池化将是您的最佳选择——这可能是查看结构的另一个原因。但是,通过您的池化,您如何知道某个对象何时不再被使用?您只是将属性设置为 null 吗?
    【解决方案2】:

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

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

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

    它需要你写一些SQL代码,但节省你的时间,因为你不需要担心打开连接,创建命令和其他事情,需要用户常规连接器

    【讨论】:

    • 谢谢,但我不需要更新这些字段,我只需要获取它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多