Linq 到对象不"persisting"更改



我使用linq通过facade对象按Id选择一组对象。这个facade有一个函数GetObjectById(string id),它返回一个MyObject。我在一个查询中根据id列表选择了一堆对象:

IEnumerable<MyObject> objects = 
   from id in ids   
   select facade.GetObjectById(id);

然后后来我在我的对象上设置了一些值,比如:

foreach(MyObject object in objects)
{
  object.someValue = "banaan";
}

稍后,当我检查对象IEnumerable时,someValue没有设置为"banaan"。

这似乎与linq的延迟执行有关,因为当我将.ToList()放在第一个查询后面时,我确实工作。然而,我认为我应该能够做这样的事情。我在这里做错了什么?或者我对你应该如何使用linq的理解是错误的?

提前谢谢。

当然是延迟执行的问题。如果再次执行查询,它将在期间再次调用facade方法,如果facade方法从某个地方加载数据(=创建新实例),则以前的更改将丢失。您的foreach是第一次执行,第一次foreach之外的检查是第二次执行。

如果您想在这种情况下对相同的实例进行操作,则必须调用ToList

第二次检查对象时,是否重新评估objects枚举?因为这会让它被称为门面。GetObjectById(id)。

请尝试具体化可枚举项。类似这样的东西:

IEnumerable<MyObject> objects = 
    (from id in ids 
     select facade.GetObjectById(id)).ToArray();

我假设您在数据来源的某个地方运行SQL服务器?

查询将保留在LINQ到SQL空间中,直到如前面两个答案中所建议的那样,调用ToList()或ToArray()或类似函数。只有到那时,它才真正成为LINQ to Object,并且是实例化的数据,它将持久存在程序的内存空间中。

这样,在您对列表进行更改后,您可以再次执行相同的查询,并获得一个没有您更改的不同列表。

也许更好的解释如下:

(from id in ids select facade.GetObjectById(id)).Where(o=>string.IsNullOrEmpty(o.Name))

这将给出一个错误,因为没有来自字符串的翻译。将IsNullOrEmpty设置为SQL。

(from id in ids select facade.GetObjectById(id)).ToList().Where(o=>string.IsNullOrEmpty(o.Name))

这不会给出错误,因为在ToList()之后,您就进入了对象空间。

相关内容

  • 没有找到相关文章

最新更新