Комментарии 16
items.Count()
Не затянули ли вы всю таблицу чтобы подсчитать количество записей?
Ну в общем то что заметил, разве что сложные отчеты это не к EF :).
Нет, там будет SELECT COUNT, я проверял (плохо). К тому же, это лишь пример.
EF нужен, чтобы универсально абстрагироваться от БД. Понятно, что разработчикам удобнее взять LinqPad, или просто написать запрос на SQL. А эту штуку можно сделать один раз, отдать пользователям, и забыть (но это не точно).
EF нужен, чтобы универсально абстрагироваться от БД. Понятно, что разработчикам удобнее взять LinqPad, или просто написать запрос на SQL. А эту штуку можно сделать один раз, отдать пользователям, и забыть (но это не точно).
О нет! Вы правы, надо же к IQueryable привести. Поправил.
Визуализировать схему базы
Я вот активно использую EF, но для такого кейса точно бы выбрал native путь, через служебные таблицы конкретной СУБД, т.к. очевидно, стандартных средств EF для метаинформации может не хватить и все-равно придется лезть «глубже».
Я сделал подобный велосипед
Лучше конечно использовать C# Source Generators
Спасибо за статью. Но к сожалению она устарела с выходом EFCore 5.0.
Так как в решении используются внутренние классы из EFCore, а в 5й версии разработчики много что изменили, особенно в части архитектуры, так что при миграции на 5ю версию EFCore пример работать не будет.
Так как в решении используются внутренние классы из EFCore, а в 5й версии разработчики много что изменили, особенно в части архитектуры, так что при миграции на 5ю версию EFCore пример работать не будет.
Здравствуйте! Нет, для перехода на NET 5 ничего, кроме версий пакетов в файле *.csproj менять не надо, всё работает без изменений (использую этот код в проекте на NET 5).
Да, вы правы. Прошу прощения. Я обновил через Nuget пакеты, и при стандартном импорте неправильно импортировалась Microsoft.EntityFrameworkCore.Design. Поэтому классы и интерфейсы были недоступны из этой библиотеки.
Однако варнинги немного внушают тревогу
Предупреждение EF1001 Microsoft.EntityFrameworkCore.Scaffolding.Internal.IScaffoldingModelFactory is an internal API that supports the Entity Framework Core infrastructure and not subject to the same compatibility standards as public APIs. It may be changed or removed without notice in any release.
Статья мне очень помогла, я такой подход называю «Динамическая модель данных», может это не совсем корректно, но выражает суть лично для меня.
Одно мне не совсем очевидно, каким образом вы осуществляете доступ к конкретным значениям записей, или осуществляете выборку записей по условию в динамике. Не могли бы вы поделиться этим опытом, хотя бы вкратце. Спасибо.
И еще бы хотел добавить, что у реверс инженеринга, или подхода DatabaseFirst, как его можно назвать, есть тоже свои ограничения. Их не много, но они все же есть.
Одно мне не совсем очевидно, каким образом вы осуществляете доступ к конкретным значениям записей, или осуществляете выборку записей по условию в динамике. Не могли бы вы поделиться этим опытом, хотя бы вкратце. Спасибо.
И еще бы хотел добавить, что у реверс инженеринга, или подхода DatabaseFirst, как его можно назвать, есть тоже свои ограничения. Их не много, но они все же есть.
— not everything about the model is presented in the database schema. For example inheritance hierarchies, owned types and table splitting will not be reverse-engineered
— also, EF Core documentation claims, that there are some column types that will not be included in the model
— nullable types will not be mapped as nullable. For example, string columns that can be null, will not be scaffolded as string? type.
Я получаю список таблиц с помощью метода:
Потом получаю информацию о полях нужной таблицы:
Потом генерирую код запроса в виде строки, компилирую и выполняю его динамически с помощью Roslyn. В статье под спойлером «Пример» есть картинки того, как это у меня выглядит.
Для упрощения работы с результатами запроса использую Z.EntityFramework.Plus.EFCore.
public IEnumerable<string> GetTableNames()
{
DbContext context = contextFactory.CreateContext();
return context.Model.GetEntityTypes.Select(e => e.Name);
}
Потом получаю информацию о полях нужной таблицы:
public TableInfo GetTableInfo(string entityName)
{
var entityType = GetEntityType(entityName);
var properties = entityType.GetProperties();
var efProperties = entityType.GetServiceProperties();
var allProperties = entityType.ClrType
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => !efProperties.Any(ep => ep.Name == p.Name));
return new TableInfo
{
EntityType = entityType,
Properties = properties,
AllProperties = allProperties,
NavProperties = allProperties.Where(p => !properties.Any(ep => ep.Name == p.Name))
};
}
public class TableInfo
{
public IEntityType EntityType { get; set; }
public IEnumerable<PropertyInfo> AllProperties { get; set; }
public IEnumerable<PropertyInfo> NavProperties { get; set; }
public IEnumerable<IProperty> Properties { get; set; }
}
Потом генерирую код запроса в виде строки, компилирую и выполняю его динамически с помощью Roslyn. В статье под спойлером «Пример» есть картинки того, как это у меня выглядит.
Для упрощения работы с результатами запроса использую Z.EntityFramework.Plus.EFCore.
Большое спасибо за развернутый ответ.
Вот про этот момент и спрашивал. Я сначала пробовал через .NET Reflection получить доступ к значениям. Но если ты начал работать с Reflection тот так и должен обращаться в дальнейшем.
Т.е. по факту, вы стоите на C# выражение LinqToSql, затем компилируете его с помощью Roslin, а затем выполняете в runtime скомпилированный ранее вами код, я правильно понял ваш ответ?
Да, очень полезная библиотека, тоже ее использую. У ее автора еще очень полезный блог по Entity Framework erikej.github.io
Потом генерирую код запроса в виде строки, компилирую и выполняю его динамически с помощью Roslyn.
Вот про этот момент и спрашивал. Я сначала пробовал через .NET Reflection получить доступ к значениям. Но если ты начал работать с Reflection тот так и должен обращаться в дальнейшем.
Т.е. по факту, вы стоите на C# выражение LinqToSql, затем компилируете его с помощью Roslin, а затем выполняете в runtime скомпилированный ранее вами код, я правильно понял ваш ответ?
Для упрощения работы с результатами запроса использую Z.EntityFramework.Plus.EFCore.
Да, очень полезная библиотека, тоже ее использую. У ее автора еще очень полезный блог по Entity Framework erikej.github.io
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Roslyn & EF Core: конструируем DbContext в runtime