Есть ли способ заставить LinqPad работать с контекстом EF Core?

Я пытаюсь выяснить, есть ли что-то, чего мне не хватает, или какой-нибудь способ взломать отсутствие поддержки (пока) для Entity Framework Core DbContexts в LinqPad. Я скомпилировал код с таргетингом на 4.6.1 (как предложено на форуме LinqPad) и попробовал драйвер "Entity Framework V7", но, как следует из его названия, я не верю, что он свидание. Он по-прежнему запрашивает файл app.config или строку подключения для конструктора.

Add context dialog

Поскольку контексты EF Core используют DbContextOptions для конструирования, а не для строк подключения, я подумал, что мог бы создать перегрузку конструктора, которая принимает строку подключения, но не обрабатывает драйвер базовой базы данных. Есть ли способ указать фабрику для построения контекста? Есть ли другие возможности? Я чувствую себя потерянным без LinqPad.

Ответ 1

Последний драйвер EFCore 1.1 LINQPad (v1.1.1.1) может правильно использовать конструктор, который принимает строку (когда эта опция выбрана в LINQPad).

Так что можно добавить следующий конструктор:

public ApplicationDbContext(string connectionString) 
    : this(new DbContextOptionsBuilder<ApplicationDbContext>()
           .UseSqlServer(connectionString).Options)
    { }

Это жестко свяжет этот экземпляр контекста с провайдером сервера SQL, но, по крайней мере, не со строкой соединения. И, кроме того, ваше приложение вряд ли когда-нибудь попытается использовать этот конструктор, EF Core никогда не ожидает/продвигает ctor. который принимает строку.

Для дополнительной безопасности вы можете обернуть этот конструктор в #if DEBUG ... #endif, чтобы он никогда не попадал в производство.

Ответ 2

Похоже, что драйвер неисправен/не обновляется. Я нашел способ обойти его, изменив DbContext.

В теории это должно сработать, но это не так:

private string _connectionString;
public ApplicationDbContext(string connectionString) : base()
{
    _connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (_connectionString == null)
        base.OnConfiguring(optionsBuilder); // Normal operation

    // We have a connection string
    var dbContextOptionsBuilder = new DbContextOptionsBuilder();
    optionsBuilder.UseSqlServer(_connectionString);
    base.OnConfiguring(dbContextOptionsBuilder);
}

Драйвер LinqPad EF Core продолжает поиск конструктора без параметров, даже если вы укажете "Через конструктор, который принимает строку". Это похоже на ошибку в драйвере.

Итак, я дал ему то, что он хотел, беззаметный конструктор. Мне пришлось жестко кодировать строку подключения, поскольку IoC/appsettings.json config reader не загружен, и я не чувствую, что загружаю его отдельно в DbContext. Но он работает и позволяет мне тестировать запросы EF Core в LinqPad с моей модели.

Это отлично работает для меня:

private bool _isDebug = false;
public ApplicationDbContext() : base()
{
    _isDebug = true;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!_isDebug)
        base.OnConfiguring(optionsBuilder); // Normal operation

    // We are in debug mode
    var dbContextOptionsBuilder = new DbContextOptionsBuilder();
    // Hardcoded connection string
    optionsBuilder.UseSqlServer("data source=XXXX;initial catalog=XXXX;persist security info=True;user id=XXXX;password=XXXX;MultipleActiveResultSets=True;App=EntityFramework");
    base.OnConfiguring(dbContextOptionsBuilder);
}

Это, помимо существующего public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }, конечно.

Изменить: Будьте осторожны, похоже, что это переопределяет поведение по умолчанию, которое может не отображаться до тех пор, пока вы не развернетесь на сервере.