I am using Linq-to-Xml to read XML and update an existing data structure. Right now I have the following code to do this:
// 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;
}
This is kind of annoying to me because I have to create a temp variable and perform the data transfer. Is there any way for me to update the testPlan variable straight from within the Linq statement, which would cut down one step? I could not get it to work by adding the update code into the .Select() statement.
The following should work:
The call to
Firstin the middle is to ensure, that only the attributes of the first descendant will be assigned to the properties oftestPlan. TheToListat the end is used to really execute the code insideSelect.Although this works, I don’t recommend using it, because it uses LINQ in a way it wasn’t created for. Furthermore, it’s easy to create it wrong:
First, testPlan will contain the attribute values of the last element in your XML, because the select code is executed for each element and overwrites the properties.ToListor a similar method that forces the execution, the code insideSelectwill never be executed.So, basically, the problem is, that you create a lot of possibilities to introduce a bug.
I would implement something like this in the following way:
This is shorter, easier to read and doesn’t violate LINQ to do something it wasn’t created for.