powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Linq for SQLite: Left join с несколькими условиями
4 сообщений из 4, страница 1 из 1
Linq for SQLite: Left join с несколькими условиями
    #39068122
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дано:
Есть 2-е модели: Валюта и История курса валют.
Выборка делается из истории "на дату". Но дата, за которую делается выборка может быть хоть прошлого века, то есть в истории могут не содержатся данные о курсах валют.
И в Истории могут быть записи, а может их вообще не быть.
Получить:
Выборку Валют с Историей (курсами) на дату.
То есть надо использовать Left Join с дополнительными условиями

Модели.
Валюта:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    [Table("DirCurrency")]
    public class DirCurrency
    {
        [Key]
        public int DirCurrencyID { get; set; }
        [Required]
        public int DirCurrencyCode { get; set; }
        [Required]
        public string DirCurrencyName { get; set; }
    }


История курса валют:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
    [Table("DirCurrencyHistory")]
    public class DirCurrencyHistory
    {
        [Key]
        public int DirCurrencyHistoryID { get; set; }
        [Required]
        public DateTime DirCurrencyHistoryDate { get; set; }
        [Required]
        public decimal? DirCurrencyRate { get; set; }
        [Required]
        public int? DirCurrencyMultiplicity { get; set; }
    }



Запрос:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
var query =
    (
        from dirCurrencies in db.DirCurrencies

        // История
        join dirCurrencyHistories1 in db.DirCurrencyHistories on dirCurrencies.DirCurrencyID equals dirCurrencyHistories1.DirCurrencyID into dirCurrencyHistories2
        from dirCurrencyHistories in dirCurrencyHistories2.

        Where(
            y => y.DirCurrencyHistoryDate ==
                (
                    //!!! Вот из-за этого ошибка: "apply joins are not supported" !!!
                    from x in db.DirCurrencyHistories
                    where x.DirCurrencyID == dirCurrencies.DirCurrencyID && x.DirCurrencyHistoryDate <= _params.HistoryDate
                    select x.DirCurrencyHistoryDate
                ).Max()
        ).
        DefaultIfEmpty()

        /*
        //Так не правильно. Т.к. если нет данных в истории, то результат будут пустой
        where
            // История (выборка максимального из истории)
            dirCurrencyHistories.DirCurrencyHistoryDate ==
                (
                    from x in db.DirCurrencyHistories
                    where x.DirCurrencyID == dirCurrencies.DirCurrencyID && x.DirCurrencyHistoryDate <= _params.HistoryDate
                    select x.DirCurrencyHistoryDate
                ).Max()
        */

        select new
        {
            DirCurrencyID = dirCurrencies.DirCurrencyID,
            Del = dirCurrencies.Del,
            DirCurrencyCode = dirCurrencies.DirCurrencyCode,
            DirCurrencyGroupID = dirCurrencies.DirCurrencyGroupID,
            DirCurrencyName = dirCurrencies.DirCurrencyName,
            DirCurrencyNameShort = dirCurrencies.DirCurrencyNameShort,

            DirCurrencyRate = dirCurrencyHistories.DirCurrencyRate == null ? 0 : dirCurrencyHistories.DirCurrencyRate,
            DirCurrencyMultiplicity = dirCurrencyHistories.DirCurrencyMultiplicity == null ? 0 : dirCurrencyHistories.DirCurrencyMultiplicity
        }
    );



SQLite выдаёт ошибку:
apply joins are not supported
Ошибку получаю из-за под-запроса в Left Join-e.
То есть нельзя в Linq for SQLite делать под-запросы.

Подскажите, можно ли как-то по другому переписать запрос? Может я сделал ошибку где-то?
...
Рейтинг: 0 / 0
Linq for SQLite: Left join с несколькими условиями
    #39068950
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
potkinДано:
Есть 2-е модели: Валюта и История курса валют.
Выборка делается из истории "на дату". Но дата, за которую делается выборка может быть хоть прошлого века, то есть в истории могут не содержатся данные о курсах валют.
И в Истории могут быть записи, а может их вообще не быть.
Получить:
Выборку Валют с Историей (курсами) на дату.
То есть надо использовать Left Join с дополнительными условиями

Модели.
Валюта:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    [Table("DirCurrency")]
    public class DirCurrency
    {
        [Key]
        public int DirCurrencyID { get; set; }
        [Required]
        public int DirCurrencyCode { get; set; }
        [Required]
        public string DirCurrencyName { get; set; }
    }


История курса валют:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
    [Table("DirCurrencyHistory")]
    public class DirCurrencyHistory
    {
        [Key]
        public int DirCurrencyHistoryID { get; set; }
        [Required]
        public DateTime DirCurrencyHistoryDate { get; set; }
        [Required]
        public decimal? DirCurrencyRate { get; set; }
        [Required]
        public int? DirCurrencyMultiplicity { get; set; }
    }



Запрос:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
var query =
    (
        from dirCurrencies in db.DirCurrencies

        // История
        join dirCurrencyHistories1 in db.DirCurrencyHistories on dirCurrencies.DirCurrencyID equals dirCurrencyHistories1.DirCurrencyID into dirCurrencyHistories2
        from dirCurrencyHistories in dirCurrencyHistories2.

        Where(
            y => y.DirCurrencyHistoryDate ==
                (
                    //!!! Вот из-за этого ошибка: "apply joins are not supported" !!!
                    from x in db.DirCurrencyHistories
                    where x.DirCurrencyID == dirCurrencies.DirCurrencyID && x.DirCurrencyHistoryDate <= _params.HistoryDate
                    select x.DirCurrencyHistoryDate
                ).Max()
        ).
        DefaultIfEmpty()

        /*
        //Так не правильно. Т.к. если нет данных в истории, то результат будут пустой
        where
            // История (выборка максимального из истории)
            dirCurrencyHistories.DirCurrencyHistoryDate ==
                (
                    from x in db.DirCurrencyHistories
                    where x.DirCurrencyID == dirCurrencies.DirCurrencyID && x.DirCurrencyHistoryDate <= _params.HistoryDate
                    select x.DirCurrencyHistoryDate
                ).Max()
        */

        select new
        {
            DirCurrencyID = dirCurrencies.DirCurrencyID,
            Del = dirCurrencies.Del,
            DirCurrencyCode = dirCurrencies.DirCurrencyCode,
            DirCurrencyGroupID = dirCurrencies.DirCurrencyGroupID,
            DirCurrencyName = dirCurrencies.DirCurrencyName,
            DirCurrencyNameShort = dirCurrencies.DirCurrencyNameShort,

            DirCurrencyRate = dirCurrencyHistories.DirCurrencyRate == null ? 0 : dirCurrencyHistories.DirCurrencyRate,
            DirCurrencyMultiplicity = dirCurrencyHistories.DirCurrencyMultiplicity == null ? 0 : dirCurrencyHistories.DirCurrencyMultiplicity
        }
    );



SQLite выдаёт ошибку:
apply joins are not supported
Ошибку получаю из-за под-запроса в Left Join-e.
То есть нельзя в Linq for SQLite делать под-запросы.

Подскажите, можно ли как-то по другому переписать запрос? Может я сделал ошибку где-то?

Безотносительно заморок с соединениями - в данном случае можно (и нужно) вычислить дату заранее и передать её в запрос.
...
Рейтинг: 0 / 0
Linq for SQLite: Left join с несколькими условиями
    #39068958
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не увидел корреляционого подзапроса.

Его можно переписать так:

history.groupby(x=>x.id).Select(x=>x.Key,x.Max(z=>z.Date))

И соединить уже с этим анонимным классом.

Не знаю, как переварит это sqlite провайдер - всегда (условно) можно вытащить на клиент и вертеть результат уже как хочешь.
...
Рейтинг: 0 / 0
Linq for SQLite: Left join с несколькими условиями
    #39069264
Фотография potkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Monochromatiqueможно (и нужно) вычислить дату заранее и передать её в запрос.
Для каждой записи дата будет своя.
То есть "Максимальных Дат" будет много - для каждой валюты своя.

Monochromatiquegroupby
Не хочу связываться с "groupby", у меня ещё есть табличка с товарами - там более 200 000 товаров и истории цен более 3 млн, одновременных пользователей минимум 30. Не потянет. Лучше под-запрос.
Но я попробую ...
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Linq for SQLite: Left join с несколькими условиями
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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