簡體   English   中英

如何通過Linq-to-XML使用數據更新現有實體?

[英]How do I update an existing entity with data via Linq-to-XML?

我正在使用Linq-to-Xml讀取XML並更新現有的數據結構。 現在,我有以下代碼可以做到這一點:

        // Load all the test plan details
        var details = doc.Descendants()
                         .Select(x => new
                         {
                             Name = x.Attribute("name").ToStringValue(),
                             DbName = x.Attribute(DATABASE_ATTR).ToStringValue(),
                             Login = x.Attribute(USERNAME_ATTR).ToStringValue(),
                             Password = x.Attribute(PASSWORD_ATTR).ToStringValue(),
                             AppSource = x.Attribute(APPSOURCE_ATTR).ToStringValue()
                         })
                         .First();


        testPlan.Name = details.Name;
        testPlan.DatabaseName = details.DbName;
        testPlan.LoginUsername = details.Login;
        testPlan.LoginPassword = details.Password;
        testPlan.ApplicationSource = details.AppSource;
    }

這讓我有點煩,因為我必須創建一個臨時變量並執行數據傳輸。 我有什么方法可以直接從Linq語句中更新testPlan變量,這可以減少一步? 我無法通過將更新代碼添加到.Select()語句中來使其工作。

以下應該工作:

doc.Descendants().First()
   .Select(x => 
           {
               testPlan.Name= x.Attribute("name").ToStringValue();
               testPlan.DatabaseName = x.Attribute(DATABASE_ATTR)
                                        .ToStringValue();
               testPlan.LoginUsername = x.Attribute(USERNAME_ATTR)
                                         .ToStringValue();
               testPlan.LoginPassword = x.Attribute(PASSWORD_ATTR)
                                         .ToStringValue();
               testPlan.ApplicationSource = x.Attribute(APPSOURCE_ATTR)
                                             .ToStringValue();
               return testPlan;
           })
    .ToList();

在中間對First的調用是為了確保僅將第一個后代的屬性分配給testPlan的屬性。 最后的ToList用於真正執行Select的代碼。

盡管此方法有效,但我不建議您使用它,因為它以一種並非為之創建的方式使用LINQ。 此外,很容易將其創建為錯誤:

  • 如果忘記了First ,則testPlan將包含XML中最后一個元素的屬性值,因為將對每個元素執行選擇代碼並覆蓋這些屬性。
  • 如果忘記了對ToList的調用或強制執行的類似方法,則Select內的代碼將永遠不會執行。

因此,基本上,問題是,您創造了很多引入錯誤的可能性。

我將通過以下方式實現這種方式:

var x = doc.Descendants.First();
testPlan.Name= x.Attribute("name").ToStringValue();
testPlan.DatabaseName = x.Attribute(DATABASE_ATTR).ToStringValue();
testPlan.LoginUsername = x.Attribute(USERNAME_ATTR).ToStringValue();
testPlan.LoginPassword = x.Attribute(PASSWORD_ATTR).ToStringValue();
testPlan.ApplicationSource = x.Attribute(APPSOURCE_ATTR).ToStringValue();

它更短,更易於閱讀,並且不會違反LINQ來執行並非針對其創建的操作。

我要做的是在TestPlan類中創建一個接受類型為details的參數的構造函數?

然后只需調用testPlan = new TestPlan(details);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM