Исключение Entity Framework: недопустимое имя объекта
Я пытаюсь создать базу данных с использованием подхода Code First. Когда я запускаю следующий код, я получаю следующее исключение. Что-то не так в полях, которые я определил? Как мы можем преодолеть это?
Исключение:
При обновлении записей произошла ошибка. Подробнее см. Внутреннее исключение.
Внутреннее исключение:
"Недопустимое имя объекта 'dbo.Dinners'.
Примечание. У меня нет такой таблицы (Dinners) в databse. Код должен создавать таблицы. Я просто дал строку подключения для идентификации сервера, как указано в EF Code First: Не удается подключиться к SQL Server. Должен ли я изменить строку соединения?
Соединения Строка:
string connectionstring = "Источник данных =; Начальный каталог = БиблиотекаReservationSystem; Интегрированная безопасность = True; Время ожидания подключения = 30";
База данных LibraryReservationSystem - это уже существующая база данных. В нем нет таблиц. Я ожидаю, что EF создаст таблицы.
Строка подключения, которую я скопировал из рабочего приложения LINQ 2 SQL. Нужно ли мне вносить какие-либо изменения в EF?
![enter image description here]()
UPDATE
Когда я включил следующий код, исключение изменилось. Теперь он говорит - "Недопустимое имя объекта" dbo.Dinner ".". Сейчас он жалуется на обеденный стол; а не обеденный стол.
protected override void OnModelCreating(DbModelBuilder modelbuilder)
{
modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
Оригинальный код
static void Main(string[] args)
{
string connectionstring = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
using (var db = new NerdDinners(connectionstring))
{
var product = new Dinner { DinnerID = 1, Title = 101 };
db.Dinners.Add(product);
int recordsAffected = db.SaveChanges();
}
}
using System.Data.Entity;
namespace LijosEF
{
public class Dinner
{
public int DinnerID { get; set; }
public int Title { get; set; }
}
public class RSVP
{
public int RSVPID { get; set; }
public int DinnerID { get; set; }
public virtual Dinner Dinner { get; set; }
}
//System.Data.Entity.DbContext is from EntityFramework.dll
public class NerdDinners : System.Data.Entity.DbContext
{
public NerdDinners(string connString): base(connString)
{
}
public DbSet<Dinner> Dinners { get; set; }
public DbSet<RSVP> RSVPs { get; set; }
}
}
ССЫЛКА
Ответы
Ответ 1
База данных LibraryReservationSystem - это уже существующая база данных. Это не имеет таблиц. Я ожидаю, что EF создаст таблицы.
Это не правильно. Если база данных существует, EF не создает никаких таблиц в этой базе данных. EF может создать базу данных, если она не существует. Это инициализатор базы данных по умолчанию CreateDatabaseIfNotExists
, который применяется, если вы не меняете его явно. Вы можете выбрать два других инициализатора: DropCreateDatabaseAlways
или DropCreateDatabaseIfModelChanges
. Но ни один из них не будет создавать таблицы только в существующей базе данных, а вместо этого удалит базу данных полностью и создаст ее с нуля, включая все таблицы.
Что вы можете сделать:
- Либо удалите базу данных вручную (например, в SSMS), затем EF создаст новую, включая таблицы
- Или используйте инициализатор
DropCreateDatabaseAlways
один раз, чтобы EF создала базу данных, включая таблицы, а затем снова удалила инициализацию.
-
Или если вы не можете удалить базу данных по любой причине, напишите SQL-код в методе Seed
, который добавляет таблицы в базу данных (Неверно, благодаря комментарию Марка Стаффорда)
- Или используйте Code-First Migrations (EF >= 4.3), чтобы добавить новые таблицы в существующую базу данных, когда вы добавили новые сущности.
Ответ 2
Ответ на @Slauma правильный - таблицы создаются при инициализации. Вероятно, проще всего просто удалить базу данных и позволить EF создать ее (если вы оставите строку соединения как есть, она создаст на локальном компьютере базу данных под названием LibraryReservationSystem; возможно, вам нужно указать явное имя хоста, если вы собираетесь использовать строка подключения в config в этой точке).
Вам понадобится что-то по строкам:
public class NerdDinnersInitializer : DropCreateDatabaseIfModelChanges<NerdDinners> { }
И вам также потребуется установить инициализатор в свой метод Main:
Database.SetInitializer(new NerdDinnersInitializer());
Слово для мудрых: НИКОГДА не развертывайте приложение с инициализатором, как указано выше. Вы можете увидеть это сообщение в блоге о том, как управлять инициализаторами через конфигурационный файл для получения более подробной информации о том, как управлять этим в производственных приложениях.
Ответ 3
Я только что столкнулся с одной и той же проблемой - я уже создал свою базу данных в SQL-окне разработки внутри нашей сети, для которой требуется проверка подлинности SQL.
Когда я запускал приложение, таблицы не создавались. Я нашел эту удивительную, но простую статью о создании Code First Database Initializer Strategy, которая сначала проверяет, существует ли база данных, а затем запускает script против базы данных для создания таблиц.
Как указано в статье - обратите внимание, что при развертывании такой стратегии при каждом запуске приложения все таблицы базы данных будут воссозданы! Эта стратегия должна выполняться только один раз.
Но вы уже это знали.
Ответ 4
Как показывает ошибка, в вашей базе данных нет таблицы с именем Dinners
.
Используете ли вы одиночные или множественные имена таблиц? т.е. ужин или ужин?
Ответ 5
Как я понял, вы ожидаете, что код будет создавать БД автоматически на основе описания ваших сущностей. Но этого не произойдет, если вы явно создадите БД. Пожалуйста, проверьте следующую ссылку http://www.simple-talk.com/dotnet/.net-framework/entity-framework-4460---learn-to-create-databases-from-the-model/
и этот учебник по EF codefirst: http://codefirst.codeplex.com/
Ответ 6
После создания ваших объектов вы можете щелкнуть правой кнопкой мыши рабочее пространство файла EDMX и выбрать "Создать базу данных из модели...". Нажмите до тех пор, пока в вашем окне не будет script. Для этого script вам нужно будет удалить шаг создания базы данных (если он есть) и перейти прямо к CREATE TABLE...
Скопировать-Вставить и выполнить в любом БД, который у вас есть. Возможно, вам придется настроить script для конкретной РСУБД.