Подтвердить что ты не робот

Entity Framework (4.3) ищет уникальное имя вместо множественного числа (когда имя объекта заканчивается на "s" )

Вот моя ситуация: Я некоторое время работаю над приложением ASP.NET MVC 3. У этого есть база данных (построенная из проекта db, я иду db-first), для которого у меня есть модель edmx, а затем набор POCOs. Мои объекты имеют множественные имена в базе данных, а POCOs имеют уникальные имена. Все прекрасно выглядит без проблем.

Или используется до тех пор, пока я не добавлю новую таблицу (называемую TransactionStatuses). Теперь все старые сущности все еще работают, но новый не работает. Когда я пытаюсь загрузить его вместе с связанной сущностью:

var transactions = (from t in db.Transactions.Include(s => s.TransactionStatus) //TransactionStatus - navigation property in Transactions to TransactionStatuses
                    where t.CustomerID == CustomerID
                    select t).ToList();

Я получаю

Недопустимое имя объекта 'dbo.TransactionStatus'.

Я даже сделал более простой тест:

List<TransactionStatus> statuses = db.TransactionStatuses.ToList();

= тот же результат.

Я обновил (и даже воссоздал) edmx из db и прошел через него взад и вперед, пытаясь выяснить, что отличается от сопоставления для dbo.TransactionStatus * es *, который совершает все это.

Если кто-то может указать мне в сторону исправления, было бы замечательно.

P.S. Отклонение плюрализации не является вариантом, спасибо.

Обновление: я понял это - мой ответ ниже.

4b9b3361

Ответ 1

Это, вероятно, происходит потому, что, хотя намерение состояло в использовании потока базы данных First, на самом деле приложение использует Code First для сопоставления. Позвольте мне объяснить немного больше, потому что это может ввести в заблуждение.: -)

При использовании базы данных First с дизайнером EF и шаблонами DbContext в Visual Studio происходят три очень важные вещи. Во-первых, новый мастер модели данных Entity добавляет строку подключения к вашему приложению, содержащую сведения о модели базы данных First (например, EDMX), чтобы при запуске приложения она могла найти эту модель. Строка подключения будет выглядеть примерно так:

<connectionStrings>
    <add name="MyEntities"
    connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\sqlexpress;initial catalog=MyEntities;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;"
    providerName="System.Data.EntityClient" />
</connectionStrings>

Во-вторых, созданный класс контекста вызывает вызов базового конструктора DbContext, определяющего имя этой строки соединения:

public MyEntities()
: base("name=MyEntities")
{
}

Это говорит DbContext, чтобы найти и использовать строку подключения "MyEntities" в конфиге. Использование "name=" означает, что DbContext будет бросать, если он не найдет строку подключения - он не будет просто продолжать и создавать соединение по соглашению.

Если вы хотите использовать Database First, тогда вы должны использовать строку подключения, такую ​​как созданная. В частности, он должен содержать данные модели (csdl, msl, ssdl из EDMX), и вы должны убедиться, что DbContext находит это. Будьте осторожны при изменении вызова базового конструктора.

Третье, что происходит, это то, что OnModelCreating переопределяется в сгенерированном контексте и делается для того, чтобы бросить:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

Это делается потому, что OnModelCreating вызывается только при использовании Code First. Это связано с тем, что OnModelCreating - это все о создании модели, но когда вы используете Database First, модель уже существует - создавать во время выполнения нечего. Поэтому, если вызывается OnModelCreating, это, вероятно, потому, что вы начали использовать Code First без значения, обычно из-за изменения строки подключения или вызова базового конструктора.

Теперь возможно, что вы хотите использовать Code First для сопоставления с существующей базой данных. Это отличный шаблон и полностью поддерживается (см. http://blogs.msdn.com/b/adonet/archive/2011/03/07/when-is-code-first-not-code-first.aspx), но вам нужно убедиться, что сопоставления настроены соответствующим образом, чтобы это работало. Если сопоставления не настроены правильно, вы получите исключения, подобные тем, которые заданы в этом вопросе.

Ответ 2

Получил! Ужасный, ужасный опыт...

Вкратце: EF не может правильно различать имена объектов, заканчивающиеся на "s" (например, "статус", "кампус" и т.д.)

Вот как я получил это и доказал.

  • Я создал и повторно создал свою оригинальную настройку несколько раз с тем же результатом.
  • Я также попытался переименовать мою таблицу в такие вещи, как TransStatus и т.п. - не повезло.
  • Пока я изучал это, я наткнулся на статью о плюрализации , где он добавил правила плюрализации для слов типа sheep и goose. Это заставило меня подумать: "Что, если проблема в фактическом имени сущности?"
  • В частности, я искал слово status и нашел этот отчет о проблеме в Connect. Я поспешил попробовать переименовать мою сущность...
  • Переименование TransactionStatuses в TransactionStates (хотя даже сохранение столбцов как StatusID) исправлено проблема! Теперь я могу получить List<TransactionState> statuses = db.TransactionStates.ToList();
  • Я думал, что проблема связана с конкретным словом status в названии... Но после того, как я громко пожаловался об этом другу, мне предложили, что, возможно, проблема в том, что слово заканчивается на "s" ... Итак Я решил проверить это.
  • Я создал другую таблицу под названием Campuses и сопоставлял POCO Campus (и обновлял edmx). Простой тест List<Campus> test = db.Campuses.ToList(); и получил ожидаемый

Недопустимое имя объекта 'dbo.Campus'.

Итак, вы идете, могучий EF не может обрабатывать плюрализацию слов, заканчивающихся на "s" . Надеюсь, следующий бедный педераст, столкнувшийся с проблемой, найдет этот вопрос и спасет его 3-4 часа от боли и разочарования.

Ответ 3

Вы упоминаете EDMX, но я не могу сказать, сначала ли вы делаете databse сначала с EDMX или кодом, а просто с помощью EDMX, чтобы узнать, что происходит.

Если вы используете Code First, вы можете использовать конфигурацию для указания имени таблицы. Аннотации данных - это [Таблица (TransactionStatuses)], свободно - modelBuilder.Entity(). ToTable ( "TransactionStatuses" ). (Я набираю аннотацию и свободный код из памяти, поэтому дважды проверяю ссылки.;))

Если вы сначала используете базу данных, SSDL должен абсолютно знать имя таблицы базы данных, поэтому я предполагаю, что вы сначала используете код, а edmx - только для исследования. (???)

HTH

Ответ 4

Вздох. Тот же тип проблемы с классом и моделью Photo and Video; он ищет таблицу фотографий и видео. Мне не нравится просто изменять имя таблицы, но не так много выбора, как выглядит.