2015-05-19 62 views
3

我想在lambda中编写一些Linq代码。这是我使用lambda的第一个代码,我在更新记录时遇到问题。 我的代码是:Linq更新问题与lambda

using (DataClasses1DataContext db = new DataClasses1DataContext()) 
{ 

    Table<NOTIF_RECIP> NOTIF_RECIP_alias = db.GetTable<NOTIF_RECIP>(); 
    Table<NOTIF_SCHED> NOTIF_SCHED_alias = db.GetTable<NOTIF_SCHED>(); 
    Table<mainframe_replication> mainframe_replication_alias = db.GetTable<mainframe_replication>(); 

    var ids = NOTIF_SCHED_alias.Select(x => x.NOTIF_RPT_ID).ToArray(); 


    foreach (string notif_sched_data in ids) 
    { 
     var repljoinmf = mainframe_replication_alias 
         .Join(NOTIF_RECIP_alias, 
          mfr => mfr.RPT_ID, 
          nr => nr.NOTIF_RECIP_ID, 
          (mfr, nr) => new 
          { 
           ReportId=mfr.RPT_ID, 
           Reportversion=mfr.RPT_VERS, 
           ReportBytes= mfr.RPT_BYTES.ToString(), 
           ReportDate=mfr.REPL_DTM.ToString(), 
           NotifId= mfr.NOTIF_ID, 
           RecipAdd=nr.NOTIF_RECIP_ADDR 
          }); 

     foreach(var repljoinmf_data in repljoinmf) 
     { 
      //DO STUFF 
      repljoinmf_data.NotifId = "Changedxyz"; 
      //db.SubmitChanges(); 
     } 
    } 
} 

我在repljoinmf_data.NotifId = "Changedxyz"; 错误获取错误说:错误2属性或索引“AnonymousType#3.NotifId”不能被分配到 - 它只是

读有人可以帮助我在这个。我认为这是因为我使用var这是匿名的,但如何解决问题。任何帮助表示赞赏。

感谢

+4

'var'不_anonymous_,它只是意味着 “让编译器决定的类型是什么” 澄清 –

+0

@DStanley感谢。 – v2v2

回答

1

由于错误提示,匿名类实例不能一旦被投射修改。

虽然你可以切换到一个强类型的类,然后重新分配的成员属性,但是,你有项目在前面的LINQ语句转换成同一个匿名类所需结果的机会:

var repljoinmf = mainframe_replication_alias 
.Join(NOTIF_RECIP_alias, mfr => mfr.RPT_ID, nr => nr.NOTIF_RECIP_ID, 
(mfr, nr) => new // Anon Class projection 
{ 
    ReportId=mfr.RPT_ID, 
    Reportversion=mfr.RPT_VERS, 
    ReportBytes= mfr.RPT_BYTES.ToString(),  
    ReportDate=mfr.REPL_DTM.ToString(), 
    NotifId= "Changedxyz", // *** No need to mutate this afterwards 
    RecipAdd=nr.NOTIF_RECIP_ADDR 
}); 

编辑,更新是不平凡的任务,建议的替代

选项#1:投影后的强类型类具有突变

添加一个新类(我猜对某些类型)

public class MyPoco 
{ 
    public int ReportId {get; set;} 
    public string Reportversion {get; set;} 
    public byte[] ReportBytes {get; set;} 
    public DateTime ReportDate {get; set;} 
    public int NotifId {get; set;} 
    public string RecipAdd {get; set;} 
} 

然后你就可以投射到(只指定类名称,而不是匿名):

(mfr, nr) => new MyPoco // Not anonymous 
{ 
    ReportId=mfr.RPT_ID, 
    ... 

然后执行修改后:

foreach(var repljoinmf_data in repljoinmf) 
{ 
    repljoinmf_data.NotifId = "SomeNewValue" 

选项#2 - 创建的方法(或函数功能)来完成复杂的逻辑

由于您似乎已经实现了所有数据,因此您可以在属性预测中自由使用复杂函数。任何可用的本地变量(关闭)可用来传递,从而功能,因为是参加拉姆达参数(mfr, nr)

因此,例如,编写一个函数来计算你的NotifId = "Changedxyz"更换:

private string DoIntensiveLogic(mainframe_replication mfr, NOTIF_RECIP nr) 
{ 
    // Do Stuff 
} 

你然后您可以在原来的匿名投影使用方法:

(mfr, nr) => new // Anon Class projection 
{ 
    ReportId=mfr.RPT_ID, 
    Reportversion=mfr.RPT_VERS, 
    ReportBytes= mfr.RPT_BYTES.ToString(),  
    ReportDate=mfr.REPL_DTM.ToString(), 
    NotifId= DoIntensiveLogic(mfr, nr), // Call the function each row 
    RecipAdd=nr.NOTIF_RECIP_ADDR 
}); 
+0

谢谢,但我需要的是每次根据一些条件更改Notifid的值。我不希望它被修改为“Changedxyz”。 – v2v2

+0

我已用两种方法更新以实现此目的。我宁愿选择第二个选项,因为它避免了新的类,并且也一步完成了投影。事后改变结果总是看起来有点讨厌国际海事组织。 – StuartLC

+0

谢谢Sir.you是生活的保护。现在一​​切正常,但当我打电话** db.SubmitChanges()**,没有改变数据库。我缺少别的东西吗?再次感谢 – v2v2

1

匿名类型是immutable,因此产生不能被改变,你必须创建一个新的类型。
要解决您的问题,您必须创建自己的类型,并在需要将来更新时避免使用匿名类型。
你的类型可能会是这样

public class ReportInfo 
{ 
    public int Id{get; set;} 
//the same thing for others properties 
} 

和您的查询看起来像这样

new ReportInfo() { 
       Id = mfr.RPT_ID, 
       Reportversion = mfr.RPT_VERS, 
       ReportBytes = mfr.RPT_BYTES.ToString(), 
       ReportDate = mfr.REPL_DTM.ToString(), 
       NotifId = mfr.NOTIF_ID, 
       RecipAdd = nr.NOTIF_RECIP_ADDR 
      }) 

比你可以轻松地更新你的财产

foreach(var repljoinmf_data in repljoinmf) 
     { 
      //DO STUFF 
      repljoinmf_data.NotifId = "Changedxyz"; 
      //db.SubmitChanges(); 
     } 

更多关于匿名类型
编译器实际上在做什么。当你写这样的一行代码:

var o = new { property1 = expression1, ..., propertyN = expressionN }; 

编译器推断每个表达式的类型,创建这些推断类型的私有字段,会为每个字段的 公共只读属性,并创建一个构造函数,接受所有这些 表达式。构造函数的代码初始化传递给它的表达式结果 中的私有只读字段。另外,编译器重写Object的Equals,GetHashCode和ToString方法,并在所有这些方法中生成代码。

+0

先生的任何建议。如何? – v2v2

+0

非常感谢主席先生,但我的坏不能标记为答案,因为只有一个可能。谢谢 – v2v2

0

如果您想稍后更改'NotifId',则可以通过id找到记录并更改属性。

例子:

var alias = mainframe_replication_alias.SingleOrDefault(mfr => mfr.NOTIF_ID == repljoinmf_data.NotifId); 
if(alias != null) 
    alias.NOTIF_ID = "Changedxyz";