LINQ - 为匿名类型的只读属性分配值

6

我想从linq中创建一个匿名类型。然后手动更改单个属性(status)的值,并将列表作为数据源提供给重复器(repeater)。但是由于它们是只读的,所以不允许我这样做。有什么建议吗?

 var list = from c in db.Mesai
                   join s in db.MesaiTip on c.mesaiTipID equals s.ID
                   where c.iseAlimID == iseAlimID
                   select new
                   {
                       tarih = c.mesaiTarih,
                       mesaiTip = s.ad,
                       mesaiBaslangic = c.mesaiBaslangic,
                       mesaiBitis = c.mesaiBitis,
                       sure = c.sure,
                       condition = c.onaylandiMi,
                       status = c.status
                   };
 foreach (var item in list)
 {
     if (item.condition==null)
     {
          item.status == "Not Confirmed";
     }
 }
 rpCalisanMesai.DataSource = list.ToList();
 rpCalisanMesai.DataBind();
3个回答

7

不要在创建列表后尝试更改值,而是在创建列表时设置正确的值。

var list = from c in db.Mesai
               join s in db.MesaiTip on c.mesaiTipID equals s.ID
               where c.iseAlimID == iseAlimID
               select new
               {
                   tarih = c.mesaiTarih,
                   mesaiTip = s.ad,
                   mesaiBaslangic = c.mesaiBaslangic,
                   mesaiBitis = c.mesaiBitis,
                   sure = c.sure,
                   condition = c.onaylandiMi,
                   status = c.onaylandiMi != null ? c.status : "Not Confirmed"
               };

此外,如果您更改属性,您的问题将执行查询两次:首先在foreach循环中,然后通过调用list.ToList()再次执行(这将创建匿名类型的新实例)。

运行得非常好,谢谢!我还有一件事情,我想对你来说应该很容易。匿名对象中的第一行是tarih=c.mesaiTarih,它是一个日期。我无法将其更改为短日期格式。请帮忙! - Jude
@Jude “not able to change it” 的意思是什么?最好提问一个新问题以提供更多背景,因为在评论中回答问题很困难。 - sloth
好的。我只是意味着我遇到了一个错误,类似于:LINQ to Entities不识别方法'System.String ToShortDateString()'方法。 - Jude
1
这是因为你正在对数据库运行查询,所以它被转换为SQL查询。但是,正如错误消息告诉你的那样,ToShortDateString 无法转换为SQL语句(在SO上会找到很多关于此主题的问题)。我不知道你代码的其余部分或用例,但我认为最好只使用 DateTime,并仅在前端格式化值(如果可能的话)。 - sloth
有时候你需要分两个阶段完成任务,先在数据库中尽可能地处理数据,生成一个匿名对象,然后使用AsEnumerable方法和select语句在内存中进行必要的操作,并创建第二个对象。 - Mant101

4

你不能修改匿名类型的属性,它们是只读的。

你需要在对象创建期间设置它。请查看@Dominic的答案以获取代码示例。


0
你可以。比如说:
var data = (from a in db.Mesai select new { ... status = new List<string>() .. }).ToList();

接下来,计算您的状态:
foreach (var item in data) {
    item.status.Add("My computed status");
} 

然后在渲染时:

foreach (var item data) {
    Response.Write(item.status[0]);
}

编辑:列表甚至可以根据您的要求进行初始化:

var data = (from a in db.Mesai select new { ... status = new List<string>(new 
string[] { c.status }) .. }).ToList();
foreach (var item in data) {
    item.status[0] = "My computed status";
} 

编辑2:看起来你必须初始化列表,最好使用例如c.rowid.ToString(),否则优化器会将相同的new List()分配给所有项目,认为这可能是某种游戏或其他东西。


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