ASP.NET 5, EF 7 и SQLite - SQLite Ошибка 1: "нет такой таблицы: блог"
Я последовал за Руководством по ASP.NET 5 о Entity Framework 7, и я заменил MicrosoftSqlServer на Sqlite, единственное различие в коде - в Startup.cs
services.AddEntityFramework()
.AddSqlite()
.AddDbContext<BloggingContext>(options => options.UseSqlite("Filename=db.db"));
Когда я запускаю веб-сайт и перебираюсь в/Блоги, я получаю сообщение об ошибке:
Microsoft.Data.Sqlite.SqliteException не обрабатывается кодом пользователя
ErrorCode = -2147467259 HResult = -2147467259 Сообщение = SQLite Ошибка 1: "нет такой таблицы: Блог" Source = Microsoft.Data.Sqlite
SqliteErrorCode = 1 StackTrace: в Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC(Int32 rc, Sqlite3Handle db) в Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior поведение) в Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior поведение) в System.Data.Common.DbCommand.ExecuteReader() в Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext() в System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() в System.Linq.Enumerable.d__1`2.MoveNext() в System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() в Microsoft.Data.Entity.Query.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext() в System.Collections.Generic.List`1..ctor(коллекция IEnumerable`1) в System.Linq.Enumerable.ToList [TSource] (источник IEnumerable`1) в EFGetStarted.AspNet5.Controllers.BlogsController.Index() в d:\arthur\documents\visual studio 2015\Projects\EFGetStarted.AspNet5\SRC\EFGetStarted.AspNet5\Контроллеры\BlogsController.cs: регель 18 InnerException:
Я понимаю это, как будто нет таблицы под названием "Блог", но когда я открываю файл .db в DB Browser для SQLite, на самом деле есть таблица под названием "Блог":
![Снимок экрана из DB Browser для SQLite с таблицей]()
Требуется ли SQLite другие изменения в коде или это ошибка в соединителе SQLite для Entity Framework?
Ответы
Ответ 1
Весьма вероятно, что база данных, фактически открываемая EF, - это не файл, который вы открываете в браузере БД. SQLite использует текущий рабочий каталог процесса, который при запуске в IIS или на других серверах может быть папкой, отличной от каталога исходного кода. (См. Проблемы https://github.com/aspnet/Microsoft.Data.Sqlite/issues/132 и https://github.com/aspnet/Microsoft.Data.Sqlite/issues/55).
Чтобы убедиться, что ваш файл базы данных находится в нужном месте, используйте абсолютный путь. Пример:
public class Startup
{
private IApplicationEnvironment _appEnv;
public Startup(IApplicationEnvironment appEnv)
{
_appEnv = appEnv;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlite()
.AddDbContext<MyContext>(
options => { options.UseSqlite($"Data Source={_appEnv.ApplicationBasePath}/data.db"); });
}
}
Ответ 2
Похоже, что все изменилось, потому что IApplicationEnvironment был заменен на IHostingEnvironment.
Удаление IApplicationEnvironment\IRuntimeEnvironment
public class Startup
{
private IHostingEnvironment _appHost;
public Startup(IHostingEnvironment appHost)
{
_appHost = appHost;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkSqlite()
.AddDbContext<MyContext>(
options => { options.UseSqlite($"Data Source={_appHost.ContentRootPath}/data.db"); });
}
}
Ответ 3
У меня была эта проблема на netcoreapp2.0
. Есть связанная проблема, которая может быть виновата, но я не хотел ее решать, переходя к ночной сборке.
Решением для меня было создать и передать SqliteConnection
вместо использования строки компоновщика.
Итак, для этой настройки:
string id = string.Format("{0}.db", Guid.NewGuid().ToString());
var builder = new SqliteConnectionStringBuilder()
{
DataSource = id,
Mode = SqliteOpenMode.Memory,
Cache = SqliteCacheMode.Shared
};
Составь для DI так:
var connection = new SqliteConnection(builder.ConnectionString);
connection.Open();
connection.EnableExtensions(true);
services.AddDbContext<SomeDbContext>(options => options.UseSqlite(connection));
Ошибка, которую я имел, использовала этот стиль init:
services.AddDbContext<SomeDbContext>(options => options.UseSqlite(builder.ConnectionString));
У моих лесов также есть одноразовый звонок:
var dbContext = serviceScope.ServiceProvider.GetService<SomeDbContext>();
dbContext.Database.OpenConnection();
dbContext.Database.EnsureCreated();
Используя этот подход, все мои экземпляры SomeDbContext
использованием SomeDbContext
будут указывать на действительную SomeDbContext
SQLite, и эта база данных будет иметь автоматически созданную схему в соответствии с моими сущностями.
Ответ 4
Взято из документации EF Core...
Запустить из Visual Studio
Чтобы запустить этот пример из Visual Studio, необходимо вручную установить рабочий каталог в качестве корневого каталога проекта. Если вы не установили рабочий каталог, выдается следующее исключение Microsoft.Data.Sqlite.SqliteException: Ошибка SQLite 1: "нет такой таблицы: блоги".
Чтобы установить рабочий каталог:
- В обозревателе решений щелкните правой кнопкой мыши проект и выберите " Свойства".
- Выберите вкладку Debug на левой панели.
- Установите Рабочий каталог в каталог проекта.
- Сохраните изменения.
Ответ 5
Я сделал это и все еще не мог загрузить базу данных. Я добавил следующий код в конструктор для контекста базы данных:
Database.EnsureCreated();
Теперь мой контекстный файл выглядит так: ![BoardGameDBContextFile]()
Он создал новую базу данных на моем новом хостинг-сайте Azure, поэтому, если вам нужно перенести много существующих данных, это не сработает. Это сработало для меня, так что я решил поделиться.