Я принял во внимание комментарии и согласился. Eval следует избегать.
Доступ к свойствам корня в объекте легко достигается с помощью obj[variable]
, но получение вложенных усложняет ситуацию.
Пример
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get может использоваться по-разному, вот ссылка на документацию lodash.get
Вы можете удалить часть отражения и просто передать типы вручную. Отражение - медленная задача, и вы не можете ожидать быстрого опыта с чем-то, что использует отражение, но, поскольку это только для первого соединения, мне лично было бы все равно, если не так важно начать очень быстро.
Первый Entity Framework Query всегда медленный, потому что EF компилирует вашу модель и генерирует отображений в памяти.
Вы можете предварительно сгенерировать эти виды отображения, используя EF Power Tools. Вот документация для этого здесь, в docs.microsoft.com .
Чтобы загрузить эти представления, вам нужно создать собственный класс DbConfiguration, например:
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration() : base()
{
var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
SetModelStore(new DefaultDbModelStore(path));
}
}
использование:
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
Подробнее о DbConfiguration: здесь [ 119]
Еще одно, что вы можете сделать, если ваше приложение не запускается в Azure SQL , - это использовать CustomManifestTokenResolver, например,
public class CustomManifestTokenResolver : IManifestTokenResolver
{
public string ResolveManifestToken(DbConnection connection)
{
return "2012";
}
}
. Вы должны добавить его в свой класс DbConfiguration
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration() : base()
{
var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
SetModelStore(new DefaultDbModelStore(path));
SetManifestTokenResolver(new CustomManifestTokenResolver());
}
}
Еще одна проблема с производительностью во время запуска - это своевременная компиляция сборок EF. Вы можете использовать ngen, чтобы обойти это (предполагается, что ваши сборки находятся в папке bin \ release.
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\release\EntityFramework.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\release\EntityFramework.dll
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\release\EntityFramework.SqlServer.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\release\EntityFramework.SqlServer.dll
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\debug\EntityFramework.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\debug\EntityFramework.dll
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\debug\EntityFramework.SqlServer.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\debug\EntityFramework.SqlServer.dll
Для общих проблем с производительностью EF у меня есть хранилище в github где я демонстрирую общие проблемы и решения этих проблем.
Обновление: добавлен трюк при запуске
Что-то, что мы используем в нашем программном обеспечении, - это выполнение пустого запроса во время запуска. Предполагая, что у нас есть контекст с именем MyContext
и DbSet с именем Customers
, мы будем писать что-то вроде этого во время запуска:
using(var db = new MyContext())
{
db.Customers.Where(x=> x.Id < 0).ToList(); // There are no negative Ids, so this will always be and empty list
}
Это переместит ваш код инициализации в фазу запуска ваше приложение. Из-за этого пользователь не будет иметь медленный опыт для первого реального запроса в системе. Вы можете даже сделать это асинхронно. Вы просто должны убедиться, что нет других вызовов вашего контекста из других потоков в в то же время, потому что DbContext не является ThreadSafe.