我正在使用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()
语句中,我无法使其工作。
答案 0 :(得分:1)
以下内容应该有效:
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中 last 元素的属性值,因为会为每个元素执行select代码并覆盖属性。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来执行未创建的内容。
答案 1 :(得分:0)
我要做的是在TestPlan类中创建一个带有类型详细信息参数的构造函数?
然后只需调用testPlan = new TestPlan(details);