Методические указания к выполнению ЛР6 - Работа с объектно-реляционной базой данных (1033957), страница 2
Текст из файла (страница 2)
var результат = from сопоставляемыйЭлемент in контейнер
where булевскоеВыражение
select сопоставляемыйЭлемент
Например, следующий запрос вернет все объекты, старше 21.
C# | Листинг №7. Получение подмножества данных |
Console.WriteLine("All persons with age == 21"); var allPersons21 = from p in persons where p.age == 21 select p; foreach (var pers in allPersons21) Console.WriteLine(pers.ToString()); |
Получение счетчиков данных
При проектировании новых пакетов данных может понадобиться знать количество элементов перед тем, как вернуть их последовательности. Для определения числа элементов, возвращаемых выражением LINQ, используется расширяющий метод Count() класса Enumerable.
Следующий запрос вернет количество всех элементов выборки.
C# | Листинг №8. Получение счетчиков данных |
Console.WriteLine("All persons count"); var allPersonsCount = (from p in persons select p).Count(); Console.WriteLine(allPersonsCount); | |
| |
Рис. 5. Результат выполнения программы №8 |
Выражения сортировки
Выражение запроса может принимать операцию orderby для сортировки элементов в подмножестве по заданному значению. По умолчанию принят порядок по возрастанию, поэтому упорядочение по умолчанию строк производится в алфавитном порядке, числовых значений – от меньшего к большему и т.д. Чтобы отсортировать в обратном порядке, следует указать операцию descending. Хотя порядок по возрастанию принят по умолчанию, можно прояснить намерения, явно указав операцию ascending.
Следующий запрос упорядочивает все элементы выборки сначала по полю fio по возрастанию, затем по убыванию.
C# | Листинг №9. Выражения сортировки |
Console.WriteLine("All persons order by ascending"); var allPersonsCount = from p in persons orderby p.fio ascending select p; foreach (var pers in allPersonsCount) Console.WriteLine(pers.ToString()); Console.WriteLine("\nAll persons order by descending"); allPersonsCount = from p in persons orderby p.fio descending select p; foreach (var pers in allPersonsCount) Console.WriteLine(pers.ToString()) |
Выражения группировки
Предложение group возвращает последовательность объектов IGrouping<TKey, TElement>, содержащих ноль или более элементов, соответствующих значению ключа группы. Например, можно сгруппировать последовательность строк в соответствии с первой буквой каждой из строк. В этом случае первая буква является ключом и имеет тип char. Она хранится в свойстве Key каждого из объектов IGrouping<TKey, TElement>. Тип ключа определяется компилятором.
Следующий запрос группирует элементы по полю cityName. Результат формируется через Анонимный тип «на лету»
C# | Листинг №10. Выражения группировки |
Console.WriteLine("All persons grouped by cityName"); var allPersonsCount = from p in persons group p by p.cityName into g select new { cityName = g.Key , pers = g }; foreach (var pers in allPersonsCount) { Console.WriteLine(pers.cityName); foreach (var g in pers.pers) Console.WriteLine(" fio = {0}, age = {1}, passport = {2}", g.fio, g.age, g.passport); } | |
| |
Рис. 7. Результат выполнения программы №10 |
Исключение дубликатов
После вызова расширяющего метода Concat() очень легко можно получить в результате излишние элементы, что иногда приемлемо. В остальных случаях может понадобиться удалить дублированные элементы данных. Для этого необходимо вызвать расширяющий метод Distinct().
C# | Листинг №12. Исключение дубликатов |
List<string> person1 = new List<string> { "Almaev", "Budilin", "Golovanov" }; List<string> person2 = new List<string> { "Tyukavin", "Budilin", "Omar" }; var personConcat = (from p in person1 select p).Concat(from p2 in person2 select p2); Console.WriteLine("Person Concat with Distinct:"); foreach (var s in personConcat.Distinct()) Console.Write(s + " ") | |
| |
Рис. 9. Результат выполнения программы №12 |
Агрегатные операции
Запросы LINQ могут также выполнять различные агрегатные операции над результирующим набором. Одним из примеров агрегации может служить расширяющий метод Count() (см. раздел 3.3). Другие возможности включают получение среднего, максимума, минимума или суммы значений за счет использования методов Average(), Max(), Min(), Sum(), соответственно. Эти методы являются членами класса Enumerable.
C# | Листинг №13. Агрегатные операции |
double[] temperature = { 2.0, -21.3, 8, -4, 0, 8.2 }; Console.WriteLine("Max temp: {0}", (from t in temperature select t).Max()); Console.WriteLine("Min temp: {0}", (from t in temperature select t).Min()); Console.WriteLine("Average temp: {0}", (from t in temperature select t).Average()); Console.WriteLine("Sum of all temps: {0}", (from t in temperature select t).Sum()); | |
Рис. 10. Результат выполнения программы №13 |
Точечный синтаксис
Вторым вариантом LINQ запросов является точечный синтаксис, реализованный через расширяющие методы и лямбда-выражения.
Например, вывести имена, которые начинаются с А, создав новые объекты на лету (с полями name и len), с сортировкой по длине (поле len):
static void Main(string[] args)
{
List<String> names = new List<String>{ "Anna", "Vasja","Kolja","Lizs","Ksenia","Annabell","Agela","Tolik","Tom"};
var arr = names.Where( x => x.StartsWith("A") ).Select( x => (new {name=x,len=x.Length} ) ).OrderBy(y => y.len);
foreach( var a in arr)
Console.WriteLine("Res - name {0}, len {1}", a.name, a.len);
Console.ReadKey();
}
Работа с различными объектами XML
Помимо возможности создания LINQ-запросов в .NET 4 предлагаются различные объекты XML, которые работают настолько хорошо, что могут иметь свое собственное место за пределами LINQ. Эти объекты могут применяться вместо непосредственной работы с DOM. Они называются вспомогательными объектами LINQ to XML, размещаются в пространстве имен System. Xml. Linq и способны значительно упростить взаимодействие с XML-документом в памяти.
В следующих разделах кратко показано, как использовать доступные в этом пространстве имен объекты.
Объект XDocument
Объект XDocument является заменой объекта XmlDocument, который применялся в .NET 3.5, с ним гораздо легче работать, чем с XML-документами. Он используется совместно с другими новыми объектами в этой же области, такими как XNamespace, XComment, XElement и XAttribute.
Одним из наиболее важных членов объекта XDocument является метод Load ():
XDocument.Load(@"С:\Hamlet.xml");
Эта операция приведет к загрузке содержимого файла Hamlet, xml в память в виде объекта XDocument. Методу Load() можно также передавать объект TextReader или Xml Reader. После этого с XML можно работать из кода:
XDocument xdoc = XDocument.Load(@"С:\Hamlet.xml");
Console.WriteLine(xdoc.Root.Name.ToString());
Console.WriteLine(xdoc.Root.HasAttributes.ToString());
Другим важным членом XDocument является метод Save (), который подобно методу Load () позволяет сохранять XML-данные на физическом диске либо в объекте TextWriter или XmlWriter:
XDocument xdoc = XDocument.Load(@"С:\Hamlet.xml");
xdoc.Save(@"С:\CopyOfHamlet.xml");
Объект XElement
С объектом XElement придется работать чаще всего. С его помощью легко создавать отдельные объекты элементов, представляющие собой как целые документы XML, так и их отдельные фрагменты. Ниже показан пример создания XML-элемента с соответствующим значением:
XElement хе = new XElement("Company", "Lipper");
Console. WnteLme (xe. ToString ());
Объект XAttribute
Другим важным фактором XML, помимо элементов, являются атрибуты. Добавлять и работать с атрибутами позволяет объект XAttribute. Ниже показан пример добавления атрибута в корневой узел <Company>:
XElement xe = new XElement("Company",
new XAttribute ("MyAttribute", "MyAttnbuteValue"),
new XElement ("CompanyName", "Lipper"),
new XElement ("CompanyAddress",
new XElement ("Address", "123 Main Street"),
new XElement ("City", "St. Louis"),
new XElement ("State", "MO"),
new XElement ("Country", "USA")));
Создание XML на основе запроса к БД
var arr = db.roads;
XDocument doc=new XDocument(new XElement("root"));
foreach (var i in arr)
{
doc.Root.Add(new XElement("road",
new XAttribute("src",i.src),
new XAttribute("dest",i.dest),
new XElement("cost",i.cost) ) );
foreach (var b in i.builders)
{
doc.Root.Elements().Last().Add(new XElement("builder",
new XAttribute("name", b.title),
new XAttribute("beg", b.year_beg),
new XAttribute("eend", b.year_end),
new XElement("per", b.period)));
}
}
doc.Save("c:\\abc.xml");
Использование LINQ для выдачи запросов к документам XML
Теперь, когда известно, как помещать XML-документы в объект XDocument и работать с различными их частями, можно посмотреть на применение LINQ to XML для выдачи запросов к XML-документам и обработки результатов.