2015-05-19 98 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";