Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何通过Linq到XML用数据更新现有实体?_C#_Linq_Linq To Xml - Fatal编程技术网

C# 如何通过Linq到XML用数据更新现有实体?

C# 如何通过Linq到XML用数据更新现有实体?,c#,linq,linq-to-xml,C#,Linq,Linq To Xml,我正在使用LINQtoXML来读取Xml并更新现有的数据结构。现在,我有以下代码来执行此操作: // Load all the test plan details var details = doc.Descendants() .Select(x => new { Name = x.Attribute(

我正在使用LINQtoXML来读取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();

中间调用“代码>第一个/代码>是为了确保第一个后代的属性将被分配给<代码>测试计划> /代码>的属性。最后的

ToList
用于真正执行
Select
中的代码

虽然这是可行的,但我不建议使用它,因为它使用LINQ的方式不是为它创建的。此外,很容易造成错误:

  • 如果忘记了
    第一个
    ,testPlan将包含XML中最后一个元素的属性值,因为select代码将针对每个元素执行并覆盖属性
  • 如果忘记调用
    ToList
    或类似的强制执行方法,则
    Select
    中的代码将永远不会执行
所以,基本上,问题是,你创造了很多可能引入一个bug

我将通过以下方式实现类似的内容:

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=newtestplan(details)

LINQ是语言集成查询;在使用对象时,故意很难(或在某些情况下不可能)更新对象。但是,既然您正在
选择中创建一个新对象,为什么不直接使用该对象呢?或者,取而代之的是,
new
创建一个类型为
testPlan
的实例,这样您就不必执行任何赋值。因为现有的测试计划结构包含我不想更改或取消的数据。我只是想用从xml查询的一些数据来更新它,我不想实例化一个新的
TestPlan
,我只想根据XMLahh更新具体的细节,我在尝试这个时没有{},这就是为什么我不能让它工作的原因。出于好奇,你为什么不推荐使用这个?@KallDrexx:见更新的答案。这说明我会怎么做。另请看德列夫对你的问题的评论的第一句话。哦,我想这更有意义。@Kalldrex:请再次检查答案。我再次更新了它,解释了LINQ方法的问题。