powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Как работать с БД ?
47 сообщений из 47, показаны все 2 страниц
Как работать с БД ?
    #39308649
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изучаю C#, как понимаю есть 100500 подходов для работы с БД. Какой изучать? Какой модный/перспективный?

Начал осваивать LinqToSQL, в целом понятно, достаточно просто, "из коробки" все работает, но наткнулся сегодня в инете на то что MS эту технологию хоронит и продвигает Entity Framework. Почитал про модели (Database First, Model First, Code First). Пытался потестить Database First в духе LinqToSQL и просто не смог, не смог добавить "ADO.NET Entity Framework" в MSVS 2015. Его просто нет. Не смог сгенерить классы по готовой БД. Не смог создать EDMX-файл, МС пишет устарело .

Отсюда вопрос: в какую сторону изучать?

Что нужно: пока пишу микросервисы, консольная прога + MSSQL, работает в автомате. Постепенно доберусь до гуя (десктоп приложение), раньше потребуется использование что-то типа SQLite, т.е. локальная СУБД не требующая установки.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308680
depend86
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
начинать учиться нужно с самых базовых вещей, с классов SqlConnection, SqlCommand, DataReader
попробуй в консольном приложении прописать строку подключения к бд (ConnectionString), подключиться, выполнить некоторый SELECT , прочитать данные и получить результат в виде массива объектов поля которых соответствуют полям в таблице

не используя никакие LinqToSQL , Entity Framework и ничего другого, все ручками.., да, будет много лишнего кода, но ты поймешь как и что устроено
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308683
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
depend86... подключиться, выполнить некоторый SELECT , прочитать данные и получить результат в виде массива объектов ...
А зачем тогда C# с кучей наработок? Я этим писательством в С++ могу заниматься. Скорость работы кода будет выше, но скорость разработки значительно медленнее. Меня интересует второе.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308706
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНачал осваивать LinqToSQL,

Припозднился ты мальца.

авторна то что MS эту технологию хоронит и продвигает Entity Framework.
Правильней - LINQ2Entities

авторПочитал про модели (Database First, Model First, Code First).
Первые две лишние.

авторНе смог сгенерить классы по готовой БД.

Это с непривычки. Выбираешь add-new-item, потом ADP.NET Entity DataModel, потом Create CodeFirst from database
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308755
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MonochromatiqueЭто с непривычки. Выбираешь add-new-item, потом ADP.NET Entity DataModel, потом Create CodeFirst from database
Везде пишут что add-new-item, но нет у меня там ADO.NET Entity DataModel. MSVS Community 2015 update 2
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308765
Agapov_stas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T , так установи пакет с nuget-а..
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308766
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TMonochromatiqueЭто с непривычки. Выбираешь add-new-item, потом ADP.NET Entity DataModel, потом Create CodeFirst from database
Везде пишут что add-new-item, но нет у меня там ADO.NET Entity DataModel. MSVS Community 2015 update 2

А вот так?
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308782
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MonochromatiqueDima Tпропущено...

Везде пишут что add-new-item, но нет у меня там ADO.NET Entity DataModel. MSVS Community 2015 update 2

А вот так?
Так тоже не очень. Еще вчера наткнулся на рекомендуемый EntityFramework Reverse POCO Generator . Сходу он у меня не заработал.

Только как понимаю это реверс Code First, т.е. сначала напиши классы в стиле Code First а потом эта штука визуализирует картинкой.

Думаю надо поизучать Code First (раз уж везде пишут что это рекомендуемый подход для EF), а схему БД я и так имею в MSSQL Managment Studio.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308785
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tdepend86... подключиться, выполнить некоторый SELECT , прочитать данные и получить результат в виде массива объектов ...
А зачем тогда C# с кучей наработок? Я этим писательством в С++ могу заниматься. Скорость работы кода будет выше, но скорость разработки значительно медленнее. Меня интересует второе.
Интересное возражение. А как это помещает достижению Вашей цели? Кстати, а какая она?
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308796
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANADima Tпропущено...

А зачем тогда C# с кучей наработок? Я этим писательством в С++ могу заниматься. Скорость работы кода будет выше, но скорость разработки значительно медленнее. Меня интересует второе.
Интересное возражение. А как это помещает достижению Вашей цели? Кстати, а какая она?
Цель - писать меньше букав кода. Меньше кода => меньше отладки => быстрее разработка. Как уже говорил 19661080 пишу на C# микроcервисы, т.е. проги без гуя работающие в полном автомате. Пока присматриваюсь к C# как альтернативе С++ в задачах не требующих особой производительности. Поэтому неинтересно заниматься велосипедостроительством оберток для запросов типа "select ... from MyTable where id = ...", тем более что велосипеды уже есть. Топик поднял чтобы выяснить каким лучше пользоваться, чтобы не тратить время на изучение всех.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308804
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TMonochromatiqueпропущено...


А вот так?
Так тоже не очень.

Что значит "не очень"? Ты по ссылкам то прошел?
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308823
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Победил. Появилась ADO.NET Entity DataModel
При установке VS надо ставить галку "MS SQL Server data tools"

Но, как уже написал, поизучаю подход Code-First, тут классы самому пописать придется, но с другой стороны будет понятнее как написанное воспринимается EF. С визардами случайно ткнешь не туда мышем и потом долго разбираешься почему стало не так работать.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308829
stomsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИзучаю C#, как понимаю есть 100500 подходов для работы с БД
В конечном счете все они надстройка над ADO.NET (те самые IDbConnection, IDbCommand, IDbDataReader, которые тебе уже рекомендовали).

Dima TКакой модный/перспективный?
Вообще Linq - это самая перспективная технология доступа к данным в мире .NET на сегодня.
Самый модный на сегодня, на сколько я понимаю, Entity Framework с моделью Code First (как уже сказали выше). Но стоит ли именно за него браться - не уверен...
Лично я пользуюсь Linq2DB . Мне его возможностей хватает. Главный недостаток этой библиотеки - то, что ее разрабатывает и поддерживает, по сути, один человек. Главное, на мой взгляд, достоинство - в ней нет ничего лишнего; ровно то, что надо от легковесного ORM (никаких ChangeTraking-ов, LazyLoad и пр. лабуды). Ну и работает быстрее, чем EF.
Кстати, Linq2DB - это то, к чему должен был бы прийти LinqToSql, если бы его не забросили.
Для микросервисов, по-моему, самое оно. Но, есть риск, что разработчик забросит проект.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308839
MSSQLAndDotNet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
щас модно XSLT, XQuery :)
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308841
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TskyANAпропущено...

Интересное возражение. А как это помещает достижению Вашей цели? Кстати, а какая она?
Цель - писать меньше букав кода.
Дак это вообще на F# надо переходить :)

А вообще меньше буков кода - это когда меньше всяких DTO, POCO, Business Objects, Services, Repositories, Mappers.
И ещё ORM-ы бывают работают не так как вам надо, или не оптимально, или в них тупо баги и приходится писать код, чтобы это обойти.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308850
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stomskyDima TИзучаю C#, как понимаю есть 100500 подходов для работы с БД
В конечном счете все они надстройка над ADO.NET (те самые IDbConnection, IDbCommand, IDbDataReader, которые тебе уже рекомендовали).
Ну так мне нужна надстройка, готовая, чтобы свою не строить.
stomskyЛично я пользуюсь Linq2DB .
Спасибо, посмотрю.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308852
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tstomskyпропущено...

В конечном счете все они надстройка над ADO.NET (те самые IDbConnection, IDbCommand, IDbDataReader, которые тебе уже рекомендовали).
Ну так мне нужна надстройка, готовая, чтобы свою не строить.Dapper?
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308902
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAА вообще меньше буков кода - это когда меньше всяких DTO, POCO, Business Objects, Services, Repositories, Mappers.
Если не злоупотреблять, то много не будет.
skyANAИ ещё ORM-ы бывают работают не так как вам надо, или не оптимально, или в них тупо баги и приходится писать код, чтобы это обойти.
Невозможно оптимально обернуть РСУБД с помощью ООП, но это не мешает в 99% случаев, в оставшемся 1% можно позаморачиваться с оптимизацией. Для простых запросов Linq генерит вполне нормальные select`ы, более сложные вещи можно вынести на сторону sql-сервера (писать ХП или view делать).
Багов хотелось бы поменьше, поэтому и хочу ширпотребное решение, чтобы баги по-максимуму уже были убраны.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308912
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДля простых запросов Linq генерит вполне нормальные select`ы, более сложные вещи можно вынести на сторону sql-сервера (писать ХП или view делать).Как измеряется сложность запроса? Количеством букв? Количеством таблиц? Количеством полей? Если да, то при каком количестве букв/таблиц/полей в запросе применять LINQ уже нельзя?

Да, через LINQ нельзя сгенерировать, например, рекурсивный SQL-запрос, данную часть SQL придётся вынести во view. Но к сложности это не имеет никакого отношения.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308933
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima TДля простых запросов Linq генерит вполне нормальные select`ы, более сложные вещи можно вынести на сторону sql-сервера (писать ХП или view делать).Как измеряется сложность запроса? Количеством букв? Количеством таблиц? Количеством полей? Если да, то при каком количестве букв/таблиц/полей в запросе применять LINQ уже нельзя?
Эмпирически. Сравнением того что LINQ нагородил и того как бы сам написал, затем изучение плана выполнения того и другого.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308941
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANADapper?
Спасибо. На первый взгляд это то что надо. Объекты есть, кода минимум, запросы в SQL, нет гимора следить что LINQ генерит. Сейчас потестю.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308969
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TАлексей Кпропущено...
Как измеряется сложность запроса? Количеством букв? Количеством таблиц? Количеством полей? Если да, то при каком количестве букв/таблиц/полей в запросе применять LINQ уже нельзя?
Эмпирически. Сравнением того что LINQ нагородил и того как бы сам написал, затем изучение плана выполнения того и другого.Ну пиши LINQ запрос так, чтобы на выходе получался нужный план выполнения SQL запроса. Так говоришь, как будто при генерации SQL запросов используется генератор случайных чисел. :-)
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39308980
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T нет гимора следить что LINQ генерит.

Дмитрий должно быть занимается _настоящим_ хай-лоад
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309014
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima Tпропущено...

Эмпирически. Сравнением того что LINQ нагородил и того как бы сам написал, затем изучение плана выполнения того и другого.Ну пиши LINQ запрос так, чтобы на выходе получался нужный план выполнения SQL запроса. Так говоришь, как будто при генерации SQL запросов используется генератор случайных чисел. :-)
Ну не всегда возможно. С LEFT JOIN все плохо, UNION не получилось заставить сделать.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309035
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Затестил Dapper
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
using System;
using System.Data.SqlClient;
using Dapper;
using System.Linq;

namespace TestDapper {
	class Program {

		public struct Test {
			public int Id;
			public string Text;
		}

		static void Main(string[] args) {
			var db = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=MyDB;User ID=user;Password=password");
			var t = db.Query<Test>("select Id, Text from Test where Id = @Id", new { Id = 6 }).SingleOrDefault();
			Console.WriteLine(t.Id + " " + t.Text);
		}
	}
}


Свобода полная. Букав немного. Классы, чтоб не долбить руками, можно нагенерить с помощью ADO.NET Entity DataModel.

Попробую переписать что-нибудь небольшое на нем.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309062
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Классы можно вообще не генерить
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
using System;
using System.Data.SqlClient;
using Dapper;
using System.Linq;

namespace TestDapper {
	class Program {

		static void Main(string[] args) {
			var db = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=MyDB;User ID=user;Password=password");
			var t = db.Query("select * from Test where Id = @Id", new { Id = 6 }).SingleOrDefault();
			Console.WriteLine(t.Id + " " + t.Text);
		}
	}
}


Dapper автоматом создает объект dynamic. Работать будет помедленнее, но это редко когда критично.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309125
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TАлексей Кпропущено...
Ну пиши LINQ запрос так, чтобы на выходе получался нужный план выполнения SQL запроса. Так говоришь, как будто при генерации SQL запросов используется генератор случайных чисел. :-)
Ну не всегда возможно. С LEFT JOIN все плохо, UNION не получилось заставить сделать.Вместо join обычно используются ассоциации. С union проблем никаких.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309128
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Классы можно вообще не генерить
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
using System;
using System.Data.SqlClient;
using Dapper;
using System.Linq;

namespace TestDapper {
	class Program {

		static void Main(string[] args) {
			var db = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=MyDB;User ID=user;Password=password");
			var t = db.Query("select * from Test where Id = @Id", new { Id = 6 }).SingleOrDefault();
			Console.WriteLine(t.Id + " " + t.Text);
		}
	}
}


Dapper автоматом создает объект dynamic. Работать будет помедленнее, но это редко когда критично.Критично отсутствие типизации при работе с данными, если использовать dynamic.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309198
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima Tпропущено...

Ну не всегда возможно. С LEFT JOIN все плохо, UNION не получилось заставить сделать.Вместо join обычно используются ассоциации. С union проблем никаких.
Пример, из недавнего.
таблицы:
Код: c#
1.
2.
3.
GroupAddr (Id, GroupId, AddrId) // Группы адресов
UserAddr (Id, UserId, AddrId, GroupAddrId) // Привязка юзера к адресам
Doc(Id, AddrId, ...) // Документы


Есть адреса и группы адресов. Юзер может быть привязан и к конкретному адресу, и к группе адресов.
Надо выбрать все документы по адресам юзера. В фильтре имеем только конкретный @UserId

В SQL просто пишется
Код: c#
1.
2.
3.
4.
select Id, AddrId, ... from Doc
    where AddrId in (
                select nAddrId from UserAddr where UserAddr.UserId = @UserId and UserAddr.nAddrId is not null
                  union select AddrId from UserAddr join GroupAddr on UserAddr.GroupAddrId = GroupAddr.Id where UserAddr.UserId = @UserId)



Заставить Linq выдать такой запрос я не смог. Вообще ничего не смог сделать чтобы обойтись одним обращением к серверу. Может конечно у меня опыта мало. Покажи как одним Linq запросом сделать тоже самое.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309199
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей ККритично отсутствие типизации при работе с данными, если использовать dynamic.
ИМХУ если запрос и обработка результата в пределах одного метода, то некритично. Если куда-то передавать, хранить, то согласен, надо сделать класс. В моем случае первое чаще: запросил из БД, сгенерил ответ, отправил.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309207
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напутал немного
Код: c#
1.
2.
3.
GroupAddr (Id, GroupId, AddrId) // Группы адресов
UserAddr (Id, UserId, AddrId, GroupId) // Привязка юзера к адресам
Doc(Id, AddrId, ...) // Документы


Есть адреса и группы адресов. Юзер может быть привязан и к конкретному адресу, и к группе адресов.
Надо выбрать все документы по адресам юзера. В фильтре имеем только конкретный @UserId

Код: c#
1.
2.
3.
4.
select Id, AddrId, ... from Doc
    where AddrId in (
                select nAddrId from UserAddr where UserAddr.UserId = @UserId and UserAddr.nAddrId is not null
                  union select AddrId from UserAddr join GroupAddr on UserAddr.GroupId = GroupAddr.GroupId where UserAddr.UserId = @UserId)
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309208
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TАлексей Кпропущено...
Вместо join обычно используются ассоциации. С union проблем никаких.
Пример, из недавнего.
таблицы:
Код: c#
1.
2.
3.
GroupAddr (Id, GroupId, AddrId) // Группы адресов
UserAddr (Id, UserId, AddrId, GroupAddrId) // Привязка юзера к адресам
Doc(Id, AddrId, ...) // Документы


Есть адреса и группы адресов. Юзер может быть привязан и к конкретному адресу, и к группе адресов.
Надо выбрать все документы по адресам юзера. В фильтре имеем только конкретный @UserId

В SQL просто пишется
Код: c#
1.
2.
3.
4.
select Id, AddrId, ... from Doc
    where AddrId in (
                select nAddrId from UserAddr where UserAddr.UserId = @UserId and UserAddr.nAddrId is not null
                  union select AddrId from UserAddr join GroupAddr on UserAddr.GroupAddrId = GroupAddr.Id where UserAddr.UserId = @UserId)



Заставить Linq выдать такой запрос я не смог. Вообще ничего не смог сделать чтобы обойтись одним обращением к серверу. Может конечно у меня опыта мало. Покажи как одним Linq запросом сделать тоже самое.Вообще без проблем. Завтра постараюсь ответить. Сейчас нет возможности, пишу с мобилы.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309209
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TАлексей ККритично отсутствие типизации при работе с данными, если использовать dynamic.
ИМХУ если запрос и обработка результата в пределах одного метода, то некритично. Если куда-то передавать, хранить, то согласен, надо сделать класс. В моем случае первое чаще: запросил из БД, сгенерил ответ, отправил.Даже если в пределах одного метода, то удобнее использовать linq и анонимный класс.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309339
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TskyANAА вообще меньше буков кода - это когда меньше всяких DTO, POCO, Business Objects, Services, Repositories, Mappers.
Если не злоупотреблять, то много не будет.
skyANAИ ещё ORM-ы бывают работают не так как вам надо, или не оптимально, или в них тупо баги и приходится писать код, чтобы это обойти.
Невозможно оптимально обернуть РСУБД с помощью ООП, но это не мешает в 99% случаев, в оставшемся 1% можно позаморачиваться с оптимизацией. Для простых запросов Linq генерит вполне нормальные select`ы, более сложные вещи можно вынести на сторону sql-сервера (писать ХП или view делать).
Багов хотелось бы поменьше, поэтому и хочу ширпотребное решение, чтобы баги по-максимуму уже были убраны.
С 99% - это Вы погорячились :)
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309385
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, Портировал твой запрос на LINQ, не вдаваясь в подробности. Могут быть ошибки, но принцип, думаю, понятен. Повторюсь, в реальной жизни join заменяется ассоциациями.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
        var userId = 123;

        var q1 =
            from u in Db.UserAddr
            where u.UserId == userId && u.nAddrId.HasValue
            select u.AddrId;

        var q2 =
            from u in Db.UserAddr
            join g in Db.GroupAddr on u.GroupId equals g.GroupId
            where u.UserId == userId
            select u.AddrId;

        var q3 =
            from addrId in q1.Union(q2)
            join doc in Db.Doc on addrId equals doc.AddrId
            select doc;

        var result = q3.ToArray();
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309407
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima T, Портировал твой запрос на LINQ, не вдаваясь в подробности. Могут быть ошибки, но принцип, думаю, понятен. Повторюсь, в реальной жизни join заменяется ассоциациями.
Затестил, select не такой
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SELECT
    [Extent4].[ID] AS [ID],
    [Extent4].[AddrID] AS [AddrID],
    [Extent4].[Text] AS [Text]
    FROM   (SELECT DISTINCT
        [UnionAll1].[AddrID] AS [C1]
        FROM  (SELECT
            [Extent1].[AddrID] AS [AddrID]
            FROM [dbo].[UserAddr] AS [Extent1]
            WHERE ([Extent1].[UserID] = @p__linq__0) AND ([Extent1].[AddrID] IS NOT NULL)
        UNION ALL
            SELECT
            [Extent2].[AddrID] AS [AddrID]
            FROM  [dbo].[UserAddr] AS [Extent2]
            INNER JOIN [dbo].[GroupAddr] AS [Extent3] ON [Extent2].[GroupID] = [Extent3].[GroupID]
            WHERE [Extent2].[UserID] = @p__linq__1) AS [UnionAll1] ) AS [Distinct1]
    INNER JOIN [dbo].[Doc] AS [Extent4] ON [Distinct1].[C1] = [Extent4].[AddrID]
-- p__linq__0: '123' (Type = Int32, IsNullable = false)
-- p__linq__1: '123' (Type = Int32, IsNullable = false)


Тут where ... in заменен на join поэтому пришлось обернуть union в select distinct, т.е. лишний вложенный запрос.
На плане видно что лишний select вызвал лишние операции.
План выполнения, сверху мой запрос, снизу Linq

В цифрах Estimated Subtree Cost (суммарная стоимость всех операций) такая
Запрос Значениемой0.0065717 linq0.0278751
Пропорции тут нет смысла считать, т.к. таблицы пустые.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309434
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТут where ... in заменен на joinДа заменён, но это принципиально ничего не меняет. Можно заменить на вложенный запрос в разделе where, но мне в данном случае join нравится больше. Но если там план выполнения плохой, то точно не из-за этого.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309437
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВ цифрах Estimated Subtree Cost (суммарная стоимость всех операций) такая
Запрос Значениемой0.0065717 linq0.0278751
Пропорции тут нет смысла считать, т.к. таблицы пустые.Ну и какой смысл сравнивать статистику выполнения запросов на пустых таблицах?
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309440
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНа плане видно что лишний select вызвал лишние операции.Твой запрос не возвращает поле Doc.Text. Вероятно, причина в этом.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309452
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima TНа плане видно что лишний select вызвал лишние операции.Твой запрос не возвращает поле Doc.Text. Вероятно, причина в этом.
Возвращает, я добавил, на картинке с планом видно текст запроса.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309457
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Ну напиши так, для чистоты эксперимента:
Код: c#
1.
2.
3.
4.
var q3 =
    from doc in Db.Doc
    where q1.Union(q2).Any(addrId  => addrId == doc.AddrId)
    select doc;



Но я в этом смысла не вижу.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309469
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНу и какой смысл сравнивать статистику выполнения запросов на пустых таблицах?
Замерил на рабочей базе, там правда записей пока не много (GroupAddr 473, UserAddr 3, Doc 4018)

ЗапросЗначениемой0.0763995linq0.0896945
быстрее на 17%
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309475
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima T,

Ну напиши так, для чистоты эксперимента:
Код: c#
1.
2.
3.
4.
var q3 =
    from doc in Db.Doc
    where q1.Union(q2).Any(addrId  => addrId == doc.AddrId)
    select doc;



Но я в этом смысла не вижу.
текст запроса
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
SELECT
    [Extent1].[ID] AS [ID],
    [Extent1].[AddrID] AS [AddrID],
    [Extent1].[Text] AS [Text]
    FROM [dbo].[Doc] AS [Extent1]
    WHERE  EXISTS (SELECT
        1 AS [C1]
        FROM ( SELECT DISTINCT
            [UnionAll1].[AddrID] AS [C1]
            FROM  (SELECT
                [Extent2].[AddrID] AS [AddrID]
                FROM [dbo].[UserAddr] AS [Extent2]
                WHERE ([Extent2].[UserID] = @p__linq__0) AND ([Extent2].[AddrID] IS NOT NULL)
            UNION ALL
                SELECT
                [Extent3].[AddrID] AS [AddrID]
                FROM  [dbo].[UserAddr] AS [Extent3]
                INNER JOIN [dbo].[GroupAddr] AS [Extent4] ON [Extent3].[GroupID] = [Extent4].[GroupID]
                WHERE [Extent3].[UserID] = @p__linq__1) AS [UnionAll1]
        )  AS [Distinct1]
        WHERE [Distinct1].[C1] = [Extent1].[AddrID]
    )
-- p__linq__0: '123' (Type = Int32, IsNullable = false)
-- p__linq__1: '123' (Type = Int32, IsNullable = false)


Так быстрее, план почти такой же как у меня, и время соответственно такое же 0.0065719
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309492
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309680
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Напоследок, тут distinct не нужен. Можно заменить Union на Concat. План должен стать лучше.
Код: c#
1.
2.
3.
4.
var q3 =
    from doc in Db.Doc
    where q1.Concat(q2).Any(addrId => addrId == doc.AddrId)
    select doc;
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309701
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КDima T,

Напоследок, тут distinct не нужен. Можно заменить Union на Concat. План должен стать лучше.
Код: c#
1.
2.
3.
4.
var q3 =
    from doc in Db.Doc
    where q1.Concat(q2).Any(addrId => addrId == doc.AddrId)
    select doc;


запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SELECT
    [Extent1].[ID] AS [ID],
    [Extent1].[AddrID] AS [AddrID],
    [Extent1].[Text] AS [Text]
    FROM [dbo].[Doc] AS [Extent1]
    WHERE  EXISTS (SELECT
        1 AS [C1]
        FROM  (SELECT
            [Extent2].[AddrID] AS [AddrID]
            FROM [dbo].[UserAddr] AS [Extent2]
            WHERE ([Extent2].[UserID] = @p__linq__0) AND ([Extent2].[AddrID] IS NOT NULL)
        UNION ALL
            SELECT
            [Extent3].[AddrID] AS [AddrID]
            FROM  [dbo].[UserAddr] AS [Extent3]
            INNER JOIN [dbo].[GroupAddr] AS [Extent4] ON [Extent3].[GroupID] = [Extent4].[GroupID]
            WHERE [Extent3].[UserID] = @p__linq__1) AS [UnionAll1]
        WHERE [UnionAll1].[AddrID] = [Extent1].[AddrID]
    )
-- p__linq__0: '123' (Type = Int32, IsNullable = false)
-- p__linq__1: '123' (Type = Int32, IsNullable = false)


План стал один-в-один как у меня, время тоже сравнялось 0.0065717.
...
Рейтинг: 0 / 0
Как работать с БД ?
    #39309705
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok
...
Рейтинг: 0 / 0
47 сообщений из 47, показаны все 2 страниц
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Как работать с БД ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]