Именно так и делается, в шаблоне указываешь куда конектится, и все. Работает для всех поддерживаемых баз данных.
Плюс такого подхода, что есть еще возможность полной кастомизации того что будет сгенерировано.
любые генераторы кода — это в принципе зло и их необходимость, это признак того, что в проекте что-то не так с архитектурой
Кхм, можете развернуть сию мысль? Пока говорилось что генерится модель из базы, что я считаю единственно правильным способом работать с ней посредством LINQ.
EF Core + CodeFirst — опять же сами себе буратино. Надизайнят класов, намапят на базу, база как-то себе построится. Именно как-то, а не как надо. Потом через годик, когда данных в таблицы накидают, поймете где просчет и бегом это рефакторить.
Ужас берет от мысли какие после этого будут миграции и дай бог данные не потеряются.
Для Flyway нам требовалась какая-то обертка, чтобы ребята не писали SQL-запросы. Им гораздо ближе оперировать в терминах ООП. Написали инструкции по работе с объектами БД, сформировался SQL-запрос и выполнился. Новая версия БД готова, прокаталась — всё хорошо, всё работает.
Странно почему ребята не посмотрели в сторону FluentMigrator. И туда и назад. Но в чистый назад я не верю. Лучше бакап перед миграцией. EF Core миграции еще тот минингит судя по фиксам и ломающим изменениям.
У Entity Framework Core есть минус — при больших нагрузках он строит не оптимальные SQL-запросы, и просадка по БД может быть существенной. Но так как у нас не высоконагруженный сервис, мы не исчисляем нагрузку сотнями RPS, мы приняли эти риски и делегировали проблему будущим нам.
У EF Core, большой минус, что он еще только родился. И если вы сидите на старых версиях — вы сами себе буратино, так как оптимизацией запросов они только начали заниматься. А там небольшой толк появляется только с .NET Core 3 — без малейшего понятия почему они так сделали, но что есть то есть.
И не при больших нагрузках, а в основном. Так складываются камешки в блоки потери производительности. Попросите ребят отключить предупреджение об client evaluation и превратить их в ошибки. Думаю 50% запросов у вас свалится. И это к лучшему, так как новая версия аннонсирует отключение client evaluation по умолчанию. Видать только так они могли сие стартануть в сроки (я их понимаю, это очень даже не просто).
Вот противоположное мнение появилось. Жава как была многословной так исталась. Питон как скриптовый язык хорош, но для больших решений это будущая попаболь.
Глаза вырывают скобочки не там? Это отдельная тема где они должны стоять. И все что вы перечислели это необязательно.
Вот работаю на маке, в свободное время, благо работодатели дали такую возможность, сам бы не решился экспереметировать. И хочу вам сказать, это слабое подобие левой руки, хотя если подготовиться скриптами за пятерку лет, то можно и работать с той же эффективностью что у меня сейчас на на винде.
И так-же, у вас были деньги на Jetbrains продукты под линухами, почему вы рассчитывали без них обойтись на винде? Ставим ReSharper и имеем все те же плюшки. Или совсем рядом Rider — тот же экспириенс IDEA, и, учитывая сколько вы «помучались» с Visual Studio, думаю до недоделок вы бы и рядом не добрались.
Извините, но это какой-то детский сад.
Все правильно на такую мелочь не надо генерировать вьюшку.
Тот же EF имеет Global Filters. С моей точки зрения полезность их сомнительна, но вам подойдет.
Также кто вам мешает понаписывать экстеншины или хелпер методы
Из минусов вижу что инклюдо-писание пострадает (Include/ThenInclude)
Если история очень важна, то можете хранить в таблице EffectiveStart, EffectiveEnd и считать что записи нет если EffectiveEnd установлена в дату меньше необходимой
Раз пошла такая пьянка, то Питон меня опять не убедил, даже скорее разочаровал своим синтакисисом. То же на C#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Triples
{
class Program
{
static IEnumerable<(int, int, int)> Triples()
{
var z = 0;
while (true)
{
++z;
for (int x = 1; x < z; x++)
for (int y = x; y < z; y++)
if (x * x + y * y == z * z)
yield return (x, y, z);
}
}
private static void TestTriples(int n)
{
var sw = new Stopwatch();
sw.Start();
var firstN = Triples().Take(n).ToList();
sw.Stop();
firstN.ForEach(i => Console.WriteLine(i));
Console.WriteLine($"{n} triples in {sw.ElapsedMilliseconds} milliseconds");
}
static void Main(string[] args)
{
TestTriples(100);
}
}
}
А вот эта конструкция что делает? Спрашиваю потому что сходу не разобрал, а гуглить по скобкам бесполезно ) first_n = [triple for _, triple in zip(range(n), triples())]
Уж не ленива ли она? Тогда что мы меряли?
Я с этим не согласен, все что они могут сделать в Roslyn это поддержать еще больше стейтментов в linq query (not i method chain). Плагин для рослина, разбирающий запрос, часто в принципе невозможен если части запроса разбросаны по функциям.
Все остальное разбирается на ура (ну не совсем ;))
Много сейчас проблем в основном с недоучетами в third party library Relinq. Ну, и мое субъективное мнение, в использовании ExpressionVisitor pattern, оно их тормозит просто неподетски.
Это был интересный челенж. За неделю управился. Да, читаем метаданные из IModel, что знал об EF Core, то и поддержал.
В основном данные черпаю из их issues. Это печальное зрелище с детскими болезнями. Но, также, должен заметить пишут его складно и вдумчиво. За пару лет может и доведут до ума. Все сводится к дикой универсальности, да и чтоб in-memory для тестов работал и еще черти знает что, и пока от этого не отходят. Вот так универсальность и приводит к ограничениям и приоритетам фиксов проблем. Народ не унывает и клепает сторед процедуры, которые их же миграции превращают в фарс.
Что делать если моя логика не транслируется в SQL?
Использовать наш экстеншин, в котором и балки поддерживаются и рекурсивные CTE и оконные функции и кастомные агрегаты, update from, insert from. Мне ну очень редко приходилось писать сторед процедуры, все потому что библиотека заточена на написание многоэтажных сиквелов через Linq и никак не прячет от вас базу данных.
Если, пока, я не заморачиваюсь над сбоями, с помощью linq2db я это дело делаю так:
using (var source = CreateSourceConnection())
using (var destination = CreateDestinationConnection())
{
// extract and transform, lazy
var sourceQuery = source.GetTable<SomeTable>()
.Select(s => new SomeDestTable{...});
// load data by 1000 records, configurable
destination.GetTable<SomeDestTable>().TableName("SomeNewName")
.BulkCopy(sourceQuery);
}
Данные влетают в базу со скоростью мысли, при чем это могут быть любые сервера и я одновременно могу делать Transform. Такой себе ETL через ORM.
Если же у вас базы на том же сервере. То почему же не сделать это одним запросом.
using (var source = CreateSourceConnection())
{
// extract and transform, lazy
var sourceQuery = source.GetTable<SomeTable>()
.Select(s => new SomeDestTable{...});
// appropriate INSERT INTO will be genarated
sourceQuery.Insert(source.GetTable<SomeDestTable>()
.DatabaseName("OtherDb").TableName("SomeNewName"));
}
Например, моего любимого аудиоплеера-комбайна под Мак нет, а двухпанельный файловый менеджер мне пришлось написать самому
Double Commander вам в помощь. Вид по умолчанию вначале вводит в ступор, но небольшой тюнинг делает его тохожим на Total Commander из мира винды. И вот уже пару лет как использую его как замену TC.
Плюс такого подхода, что есть еще возможность полной кастомизации того что будет сгенерировано.
Кхм, можете развернуть сию мысль? Пока говорилось что генерится модель из базы, что я считаю единственно правильным способом работать с ней посредством LINQ.
EF Core + CodeFirst — опять же сами себе буратино. Надизайнят класов, намапят на базу, база как-то себе построится. Именно как-то, а не как надо. Потом через годик, когда данных в таблицы накидают, поймете где просчет и бегом это рефакторить.
Ужас берет от мысли какие после этого будут миграции и дай бог данные не потеряются.
Странно почему ребята не посмотрели в сторону FluentMigrator. И туда и назад. Но в чистый назад я не верю. Лучше бакап перед миграцией. EF Core миграции еще тот минингит судя по фиксам и ломающим изменениям.
У EF Core, большой минус, что он еще только родился. И если вы сидите на старых версиях — вы сами себе буратино, так как оптимизацией запросов они только начали заниматься. А там небольшой толк появляется только с .NET Core 3 — без малейшего понятия почему они так сделали, но что есть то есть.
И не при больших нагрузках, а в основном. Так складываются камешки в блоки потери производительности. Попросите ребят отключить предупреджение об client evaluation и превратить их в ошибки. Думаю 50% запросов у вас свалится. И это к лучшему, так как новая версия аннонсирует отключение client evaluation по умолчанию. Видать только так они могли сие стартануть в сроки (я их понимаю, это очень даже не просто).
Глаза вырывают скобочки не там? Это отдельная тема где они должны стоять. И все что вы перечислели это необязательно.
Вот работаю на маке, в свободное время, благо работодатели дали такую возможность, сам бы не решился экспереметировать. И хочу вам сказать, это слабое подобие левой руки, хотя если подготовиться скриптами за пятерку лет, то можно и работать с той же эффективностью что у меня сейчас на на винде.
И так-же, у вас были деньги на Jetbrains продукты под линухами, почему вы рассчитывали без них обойтись на винде? Ставим ReSharper и имеем все те же плюшки. Или совсем рядом Rider — тот же экспириенс IDEA, и, учитывая сколько вы «помучались» с Visual Studio, думаю до недоделок вы бы и рядом не добрались.
Все правильно на такую мелочь не надо генерировать вьюшку.
Тот же EF имеет Global Filters. С моей точки зрения полезность их сомнительна, но вам подойдет.
Также кто вам мешает понаписывать экстеншины или хелпер методы
Из минусов вижу что инклюдо-писание пострадает (Include/ThenInclude)
Если история очень важна, то можете хранить в таблице EffectiveStart, EffectiveEnd и считать что записи нет если EffectiveEnd установлена в дату меньше необходимой
Но опять же страдает инклюдописание, что-то тут недодумали. Так бывает когда продукт пишут те кто его полноценно не использует (sarcasm)
...
(96, 128, 160)
(36, 160, 164)
(99, 132, 165)
(65, 156, 169)
(119, 120, 169)
(26, 168, 170)
100 triples in 6 milliseconds
А вот эта конструкция что делает? Спрашиваю потому что сходу не разобрал, а гуглить по скобкам бесполезно )
first_n = [triple for _, triple in zip(range(n), triples())]
Уж не ленива ли она? Тогда что мы меряли?
Все остальное разбирается на ура (ну не совсем ;))
Много сейчас проблем в основном с недоучетами в third party library Relinq. Ну, и мое субъективное мнение, в использовании ExpressionVisitor pattern, оно их тормозит просто неподетски.
В основном данные черпаю из их issues. Это печальное зрелище с детскими болезнями. Но, также, должен заметить пишут его складно и вдумчиво. За пару лет может и доведут до ума. Все сводится к дикой универсальности, да и чтоб in-memory для тестов работал и еще черти знает что, и пока от этого не отходят. Вот так универсальность и приводит к ограничениям и приоритетам фиксов проблем. Народ не унывает и клепает сторед процедуры, которые их же миграции превращают в фарс.
Использовать наш экстеншин, в котором и балки поддерживаются и рекурсивные CTE и оконные функции и кастомные агрегаты, update from, insert from. Мне ну очень редко приходилось писать сторед процедуры, все потому что библиотека заточена на написание многоэтажных сиквелов через Linq и никак не прячет от вас базу данных.
Данные влетают в базу со скоростью мысли, при чем это могут быть любые сервера и я одновременно могу делать Transform. Такой себе ETL через ORM.
Если же у вас базы на том же сервере. То почему же не сделать это одним запросом.
Double Commander вам в помощь. Вид по умолчанию вначале вводит в ступор, но небольшой тюнинг делает его тохожим на Total Commander из мира винды. И вот уже пару лет как использую его как замену TC.
Встречный вопрос, вы в своих спецификациях ногу не сломали? Долго ли ищите корень зла при правке багов?
До этого патерна я не дошел, вот не надо было. Даже больше, он меня слегка пугает, что можно запутаться в клубок и из этого не выпутаться.
Для таких вещей я делаю просто Extension метод, который накладывает фильтр как тунель.