EDIT:. codice aggiornato con ToDictionary
approccio per chiarezza ed efficienza.
Puoi provare il seguente esempio. Se si rimuove Record
dalla riga select new Record
, verrà restituito un tipo anonimo e funzionerà ancora. La tua classe Record
dovrebbe avere un costruttore parametrico predefinito per utilizzare l'inizializzatore dell'oggetto se hai fornito altri costruttori (funzionerà anche se non hai costruttori). Altrimenti puoi usare i costruttori disponibili invece dell'inizializzatore dell'oggetto.
Si noti che l'uso di Single()
e Value
presuppone che l'XML sia ben formato senza elementi mancanti.
var xml = XElement.Parse(@"<records>
<record index=""1"">
<property name=""Username"">Sven</property>
<property name=""Domain"">infinity2</property>
<property name=""LastLogon"">12/15/2009</property>
</record>
<record index=""2"">
<property name=""Username"">Josephine</property>
<property name=""Domain"">infinity3</property>
<property name=""LastLogon"">01/02/2010</property>
</record>
<record index=""3"">
<property name=""Username"">Frankie</property>
<property name=""Domain"">wk-infinity9</property>
<property name=""LastLogon"">10/02/2009</property>
</record>
</records>");
var query = from record in xml.Elements("record")
let properties = record.Elements("property")
.ToDictionary(p => p.Attribute("name").Value, p => p.Value)
select new Record
{
Index = record.Attribute("index").Value,
Username = properties["Username"],
Domain = properties["Domain"],
LastLogon = properties["LastLogon"]
};
foreach(var rec in query)
{
Console.WriteLine("ID: {0} User:{1} Domain:{2} LastLogon:{3}", rec.Index, rec.Username, rec.Domain, rec.LastLogon);
}
EDIT: Ho aggiornato il codice di esempio sopra con l'approccio ToDictionary
che è più pulito e veloce. In base ai miei sforzi di benchmarking, il più veloce è stato ToDictionary
, seguito da Func
e quindi l'approccio Where
.
query originale
var query = from record in xml.Elements("record")
let properties = record.Elements("property")
select new Record
{
Index = record.Attribute("index").Value,
Username = properties.Where(p => p.Attribute("name").Value == "Username").Single().Value,
Domain = properties.Where(p => p.Attribute("name").Value == "Domain").Single().Value,
LastLogon = properties.Where(p => p.Attribute("name").Value == "LastLogon").Single().Value
};
query con Funz
ridondanza della query originale può essere ridotto utilizzando il seguente codice:
Func<XElement, string, string> GetAttribute =
(e, property) => e.Elements("property")
.Where(p => p.Attribute("name").Value == property)
.Single().Value;
var query = from record in xml.Elements("record")
select new Record
{
Index = record.Attribute("index").Value,
Username = GetAttribute(record, "Username"),
Domain = GetAttribute(record, "Domain"),
LastLogon = GetAttribute(record, "LastLogon")
};
perfict! Ho cercato di capire questo per 2-3 giorni ora. La mia fronte è dolorante e rossa. Quali libri si consiglia di controllare LINQ (e C#). –
@Sunzaru Mi piace LINQ in Action (http://www.amazon.com/dp/1933988169/) o potresti volere un libro C# 4.0/.NET 4.0 per coprire parte del nuovo materiale. C# 4.0 in a Nutshell è buono ma copre molto materiale. Consiglio inoltre di scaricare LINQPad (http://www.linqpad.net/) e di esaminare gli esempi di Nutshell forniti con esso (creati dall'autore del libro). Puoi anche scaricare i campioni LINQ in Action attraverso di essa. Forse lo fai prima di acquistare un libro :) –
l'ho provato oggi c'era un tempo medio di processo di 120MS. ma in quei 120MS cercavo anche alcuni altri indicatori non menzionati sopra. veloce .. slick e zomg .. mooolto molto meglio di "Modifica-> Trova". grazie ancora! –