|
Posted
over 2 years
ago
by
Naf2000
У сущности есть свойство абстрактного типа
class Entity
{
public IForeign Foreign {get;init;}
}
Сущность должна отображаться на таблицу с двумя полями
fData int — внутренние данные
fType int — интерпретация типа
Как сделать маппинг двух
... [More]
полей на одно свойство, чтобы в зависимости от поля fType создавался тот или иной конкретный объект? fData — общие для всех IForeign данные (через конструктор или свойство инициализации).
Ну и в обратную сторону на таблицу
[Less]
|
|
Posted
almost 3 years
ago
by
bisoft
Привет всем,
Обнаружил, что метод Insert при вставке записи в таблицу с автоинкрементным ключем и заданным значением все равно вставляет новый ключ.
Попробовал обойти и вставлять с помощью
Connection.BulkCopy(new BulkCopyOptions() {
... [More]
KeepIdentity = true }, result);
Записи вставились как надо, но обнаружилась следующая ошибка. При вставке через BulkCopy записи с типом дата вставляются в формате "2023-10-01" и в этом случае
при запросе between '2023-10-01' and '2023-10-30' записи с датой 2023-10-01 в интервал не попадают.
А вот если даты будут в базе в формате "2023-10-01 00:00:00" (просто Insert их в таком виде и вставляет) то тогда попадают.
Причем выполнение запроса вручную возвращает все записи, а в программе их уже нет.
[Less]
|
|
Posted
over 3 years
ago
by
Naf2000
Имеем систему классов:
class Ref
where TEntity : Entity
{
public long ID { get; init; }
public TEntity Data => default!;
}
abstract class Entity
{
[PrimaryKey, Identity]
... [More]
public long ID { get; init; }
}
abstract class Catalog : Entity
{
[Column]
public string Name { get; init; } = default!;
}
[Table("Persons")]
class Person: Catalog
{
}
[Table("Storages")]
class Storage : Catalog
{
public Ref Manager { get; init; } = default!;
//public Person ManagerData { get; init; } = default!;
}
Ref — оболочка для агрегации и внешнего ключа.
Однако выдает ошибку, что не может разобрать написанное:
's.Manager.Data.Name' cannot be converted to SQL.
Вот код:
var builder = new FluentMappingBuilder(context.MappingSchema);
builder.Entity().Property(s => s.Manager.ID).HasColumnName(nameof(Storage.Manager));
builder.Entity().Association(s => s.Manager.Data, (s, p) => s.Manager.ID == p.ID);
builder.Build();
var query = context.GetTable().Select(s => s.Manager.Data).Select(p => new { p.Name });
Стоит раскомментировать //public Person ManagerData { get; init; } = default!;
и всюду заменить Manager.Data на ManagerData как всё работает.
Можно в принципе использовать ассоциации, написанные "через вторую точку": s => s.Manager.Data вопрос?
[Less]
|
|
Posted
over 3 years
ago
by
Berill
Доброе время суток.
Столкнулся с проблемой при использовании linq2db.cli для генерации моделей данных.
Все делаю как описано тут (https://linq2db.github.io/articles/CLI.html).
Пробую вариант кастомизации с отдельным assembly. Создал
... [More]
отдельный проект библиотеки (TargetFramework netcoreapp3.1).
Lib csproj
netcoreapp3.1
9
true
Добавил "пустой" Interceptor
Код public class MyScaffoldInterceptor : ScaffoldInterceptors
{
private ScaffoldOptions Options { get; }
public MyScaffoldInterceptor(ScaffoldOptions options)
{
this.Options = options;
}
}
Компиляция успешная, все нужные файлы в "bin\Debug\netcoreapp3.1" есть, включая DataModelsCustomization.deps.json. Идем дальше.
Создал консольное приложение, добавил Project Reference на библиотеку с кастомизациями.
App csproj
Exe
netcoreapp3.1
9
Создал каталог DataModels внутри проекта консольного приложения. Поместил туда database.json файл
database.json {
"general": {
"provider": "SqlServer",
"connection": "",
"overwrite": true
}
}
В терминале выполняю команду:
D:\PROJECTS\Examples\Linq2Db.NetCore\Linq2Db.NetCore\DataModels> dotnet linq2db scaffold -i database.json --customize ..\bin\Debug\netcoreapp3.1\DataModelsCustomization.dll
В результате получаю ошибку:
AssemblyResolve path: D:\PROJECTS\Examples\Linq2Db.NetCore\Linq2Db.NetCore\bin\Debug\netcoreapp3.1
Unhandled exception: DependencyContext.Load cannot load interceptor assembly
at LinqToDB.CommandLine.ScaffoldCommand.SetupInterceptorsDependencyResolver(String assemblyFolder, Assembly interceptorsAssembly)
at LinqToDB.CommandLine.ScaffoldCommand.LoadInterceptorsFromAssembly(String assemblyPath, ScaffoldOptions options)
at LinqToDB.CommandLine.ScaffoldCommand.LoadInterceptors(String interceptorsPath, ScaffoldOptions options)
at LinqToDB.CommandLine.ScaffoldCommand.Execute(CliController controller, String[] rawArgs, Dictionary`2 options, IReadOnlyCollection`1 unknownArgs)
at LinqToDB.CommandLine.CliController.Execute(String[] args)
at LinqToDB.Tools.Program.Main(String[] args)
В каталоге "bin\Debug\netcoreapp3.1" нет только одного файла: DataModelsCustomization.deps.json.
Как только я его копирую вручную из каталога куда складывается результат сборки библиотеки "DataModelsCustomization\bin\Debug\netcoreapp3.1", все проходит успешно, модели генерируются. Пока что никак не могу найти способа его автоматического копирования при сборке проекта.
Пробовал добавлять "true" в файл проекта приложения, не помогло.
Можно конечно выполнить терминальную команду, находясь в каталоге библиотеки
D:\PROJECTS\Examples\Linq2Db.NetCore\DataModelsCustomization> dotnet linq2db scaffold -i database.json --customize bin\Debug\netcoreapp3.1\DataModelsCustomization.dll
Но я хочу, чтобы модели данных были в проекте приложения. Или действительно надо генерировать модели в проекте с кастомизациями? В документации (https://linq2db.github.io/articles/CLI.html) об этом ничего не сказано.
Как вариант, еще можно добавить поле output в json файл.
Буду благодарен, если объясните что я делаю не так.
UPD:
Убрал Project Reference на библиотеку с кастомизацией и выполнил команду
dotnet linq2db scaffold -i database.json --customize ..\..\DataModelsCustomization\bin\Debug\netcoreapp3.1\DataModelsCustomization.dll
Может именно такая команда и имелась в виду в документации?!
[Less]
|
|
Posted
about 5 years
ago
by
Naf2000
Допустим в таблице есть строковые поля X, Y.
Сами по себе они не отображаются в свойства класса.
А хочется, чтобы в свойство MyValue объекта класса можно было передать значение некоторого выражения из них
например, описанного так:
... [More]
Expressionstring>> expr = (e) => e.X+":"+e.Y;
Чтобы каждый раз не писать вручную:
.Select(t => new MyEntity(t.Id) {Value=t.X+":"+t.Y})
Ну вот как будто с этим выражением есть computed field соответствующее свойству поля.
[Less]
|
|
Posted
about 5 years
ago
by
artelk
Ок, допустим я среднестатистический senior, для которого технические аргументы при выборе инструмента работы с базой имеют значение. Я открываю документацию linq2db и мне все нравится — гибкость, расширяемость; то, что решается конкретная
... [More]
задача сделать статически типизированный sql, который ещё и composable и прочие хорошие слова; а нерешимая на практике задача, например, по достижению persistence ignorance, не решается, что даёт основание подозревать, что авторы что-то понимают в жизни.
Я делаю POC по переносу самых заковыристых кусков проекта (где запрос собирался путём склеивания строк) на linq2db и меня все устраиваетустраивает: how to teacher linq и трюк с Compile() позволили сделать то, что мне нужно.
Далее мне нужно продать это решение и возникают такие вопросы: а насколько linq2db зрелый продукт, много ли в нём багов, поддерживается ли он какой-нибудь большой компанией, на сколько он распространен и т.п.
Если использовать в проекте какой-нибудь Dapper, то ответы сразу находятся: Dapper все знают, он разработан и используется в stackoverflow, он позиционируется как легковесная альтернатива ORM (первой версии LinqToSql на момент разработки), он на столько примитивен, что баги там врятли есть.
Ответы по Linq2Db: он достаточно наворочен и универсален, так что баги там наверняка есть; с распространённость не очень, судя по документации; в последнее время поддерживается, в основном, парочкой энтузиастов (справедливости ради, очень крутых разработчиков): sdanyliv и MaceWindu; IT временно самоустранился.
Что, как мне представляется, добавило бы аргументов в пользу выбора linq2db:
1. Success stories, список компаний и продуктов, использующих linq2db. Подозреваю, что он используется много кем, не только тремя "Notable open-source users" из документации.
2. Наличие платной поддержки очень бы помогло.
[Less]
|
|
Posted
about 5 years
ago
by
Naf2000
Имеется простейшая схема базы
Можно ли настроить linq2db так, чтобы не писать явно внешний ключ в классе Order:
[Table("Partners")]
class Partner
{
[PrimaryKey, Identity]
public long ID { get; set; }
... [More]
[Column]
public string Name { get; set; }
}
[Table("Orders")]
class Order
{
[PrimaryKey, Identity]
public long ID { get; set; }
[Column]
public string Number { get; set; }
[Association(ThisKey = "Partner", OtherKey = "ID")]
public Partner Partner { get; set; }
}
И при этом было доступно примерно такое:
var query = db.GetTable().Select(_=>_.Partner.Name);
var list = query.ToList();
[Less]
|
|
Posted
about 5 years
ago
by
Serginio1
Как известно Хранимые процедуры CLR еще в 2005 MS SQL.
Но о широком использовании не слышал.
Наприер в 1С Тест Гилева показал, что файловая быстрее файловая база на интерпретаторе быстрее SQL.
Из-за сложности алгоритмов тяжело вытащить все
... [More]
данные одним запросом. Приходится гонять данные с сервера на клиента по нескольку раз. Отсюда и тормоза.
Но вот если обязанности сервера приложений возьмут на себя Хранимые процедуры CLR ситуация может резко измениться.
Но теперь и инстрeменты на сервере SQL должны быть аналогичные что на сервере приложений, а именно доступ через Linq
[Less]
|
|
Posted
about 5 years
ago
by
LevLimin
Парочка вопросов.
1. Есть ли в LinqToDb описывать модели в xml?
В одном из проектов это одно из требований.
Пока придумал только одно, читать самому xml с моделями и через FluentMapper настраивать.
Но вдруг есть уже готовые средства?
2.
... [More]
Можно ли сделать свой атрибут и навесить его на класс/свойство, что бы построитель запросов его вызывал?
[Less]
|
|
Posted
over 5 years
ago
by
artelk
https://linq2db.github.io/articles/FAQ.html#which-async-model-linq-to-db-use
Почему не false везде, раз самой библиотеке этот контекст не нужен?
// Linq2Db library method
async Task GetFooAsync()
{
//...
await
... [More]
SomethingElseAsync().ConfigureAwait(Configuration.ContinueOnCapturedContext);
//...
return ...;
}
// Client side code
async Task UIMethodAsync()
{
var foo = await GetFooAsync().ConfigureAwait(true); // или просто await GetFooAsync();
lbl1.Text = "Done";
}
В клиентском коде контекст восстановится, даже если Configuration.ContinueOnCapturedContext был false.
[Less]
|