使用LINQ仅从表中获取所需的列以修改和保存记录会产生典型错误

时间:2015-09-12 18:54:47

标签: c# .net entity-framework linq

所以我尝试的只是从表中获取那些必须更新的列,我尝试了如下:

var user = (from u in context.tbl_user where u.e_Id == model.Id select 
           new { u.first_name, u.last_name, u.role, u.email, u.account_locked })
           .FirstOrDefault();

但是当我尝试为获取的数据分配新值时,如下所示

user.first_name = model.FirstName;

我看到以下错误显示

Error Image

  

属性或索引器'匿名类型:字符串first_name,字符串   last_name,string role,string email,bool account_locked.first_name'   无法分配 - 它是只读的

但是当我从表中检索所有值而没有过滤如下时,它工作正常。

var user = (from u in context.tbl_user where u.e_Id == model.Id select u).FirstOrDefault();

为什么它不能用于第一次查询。我在许多网站上都读过,在性能和安全性方面只能从数据库中检索所需的属性。但我真的无法理解我选择的第一种方法有什么问题。任何解释都非常感谢。

更新

是否还有其他方法可以获取所需的列并更新它们并将其存储回来?

3 个答案:

答案 0 :(得分:3)

Anonymous Types属性是只读的,因此您无法更改它们。

停止对代码执行micro-optimizingpremature-optimization。尝试编写正确执行的代码,然后如果您以后遇到性能问题,请分析您的应用程序并查看问题所在。如果你有一段代码由于找到最短和最长的字符串而出现性能问题,那么就开始优化这部分。

  

我们应该忘记效率低,大约97%的时间说:   过早优化是万恶之源。但我们不应该通过   我们在关键的3%中获得机会 - 唐纳德克努特

如果您只想获取特定列,可以创建自定义类并在查询中填充属性,就像其他人提到的那样。

答案 1 :(得分:3)

正如其他人所说anonymous type是只读的,为了达到你想要的目的,你必须为它创建一个具有所需属性的类型:

public class User
   {
       public string FirstName {get;set;}
       public string LastName {get;set;}
       .....................
       .....................
   }

然后,你必须在你的linq查询中使用它:

var user = (from u in context.tbl_user 
            where u.e_Id == model.Id
            select new User 
                  { 
                     FirstName = u.first_name,
                     LastName =  u.last_name,
                     ......................,
                     ..................... 
                   }).FirstOrDefault(); 

答案 2 :(得分:1)

匿名类型是设计为只读的。

为了检索您可以编辑的内容,您必须创建一个类并在该类中选择您的实体,如下所示:How to use LINQ to select into an object?

或者在这里:

var user = (from u in context.tbl_user where u.e_Id == model.Id select 
           new User_Mini { u.first_name, u.last_name, u.role, u.email, u.account_locked })
           .FirstOrDefault();

注意:在编辑此新对象时,您将无法调用context.SubmitChnages()。你可以这样做:LINQ to SQL: how to update the only field without retrieving whole entity

这将允许您仅更新对象的某些部分。