В Entity Framework получение значения столбца идентификаторов после вставки - PullRequest
10 голосов
/ 10 июня 2011

Я использую EF4.Я хочу вставить новый MyObject в базу данных.MyObject имеет два поля:

Id: int (Identity) и Name: string

Как я видел в документации, Entity Framework должен устанавливать MyObject.Id в значение, сгенерированное базой данных послевызов SaveChanges (), но в моем случае этого не происходит.

using (var context = new MyEntities())
{
    var myObject = MyObjects.CreateMyObject(0, "something"); // The first parameter is identity "Id"
    context.MyObjects.AddObject(myObject);
    context.SaveChanges();
    return myObject.Id; // The returned value is 0
}

ОБНОВЛЕНИЕ:

Это происходит в одном из моих объектов, и другие работают нормально,Кстати, я проверил, и столбец БД - это идентификатор, а для StoreGeneratedPattern установлено значение Идентичность.Вот SSDL.Я не вижу никакой разницы.Первый из них работает неправильно:

    <EntityType Name="OrgUnit">
      <Key>
        <PropertyRef Name="Srl" />
      </Key>
      <Property Name="Srl" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
      <Property Name="TypeId" Type="smallint" Nullable="false" />
      <Property Name="Name" Type="varchar" Nullable="false" MaxLength="80" />      
    </EntityType>

    <EntityType Name="OrgType">
      <Key>
        <PropertyRef Name="Srl" />
      </Key>
      <Property Name="Srl" Type="smallint" Nullable="false" StoreGeneratedPattern="Identity" />
      <Property Name="Title" Type="varchar" Nullable="false" MaxLength="120" />
      <Property Name="Options" Type="int" Nullable="false" />
    </EntityType>

Обновление успешно выполнено в базе данных, и идентификатор создан, но объект сущности не обновлен с новым идентификатором.

Ответы [ 7 ]

11 голосов
/ 10 июня 2011

В этом случае ваша модель EF, вероятно, устарела - EF должна автоматически получить ваш новый идентификатор из базы данных.Попробуйте обновить модель EF.

Свойства вашего столбца идентификации должны выглядеть следующим образом в вашей модели EDMX:

enter image description here

6 голосов
/ 28 ноября 2012

Если вы используете провайдер Oracle Entity Framework 4, как я, из ODP.NET, в Designer есть ошибка. Просто выбрать значение Identity в выпадающем списке не подойдет. Это пометит концептуальное свойство в концептуальной модели с

аннотация: StoreGeneratedPattern = "Identity"

как в

<Property Type="Int32" Name="Id" Nullable="false" cg:SetterAccess="Private" annotation:StoreGeneratedPattern="Identity" />

Но он не сможет сделать то же самое для модели хранения, т.е. вам нужно сделать это вручную. Найдите свойство (в моем случае ID) в интересующем EntityType и добавьте StoreGeneratedPattern = "Identity" .

    <EntityType Name="PROBLEMI">
      <Key>
        <PropertyRef Name="ID" />
      </Key>
      <Property Name="ID" Type="number" Nullable="false" Precision="10" StoreGeneratedPattern="Identity" />

Мне не известна та же ошибка в поставщике SQL EF, потому что я ее не использовал.

4 голосов
/ 10 июня 2011

Это должно "просто работать".Убедитесь, что столбец DB на самом деле равен IDENTITY, а для StoreGeneratedPattern установлено значение Identity в EDMX.

2 голосов
/ 23 мая 2012

Если вы используете Linq To Entities и получаете эту ошибку, даже если вы следовали советам marc_s (которые действительно хороши), вы должны посмотреть на свои объекты прямо в edmx (представление xml) и проверить, есть ли у них следующий атрибут:

    <EntityType Name="MyEntity">
      <Key>
        <PropertyRef Name="pk" />
      </Key>
      <Property Name="pk" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
      <Property Name="value" Type="float" Nullable="false" />
    </EntityType>

StoreGeneratedPattern = "Identity" также требуется.

2 голосов
/ 11 июня 2011

вау! это был кошмар, но наконец я решил его, хотя я не понимал, в чем проблема. Может быть, это помогает кому-то с той же проблемой.

  1. Сгенерировать скрипт для создания таблицы и ее данных.
  2. Оставь стол.
  3. Запустите скрипт.
1 голос
/ 06 июня 2012

Я столкнулся с этим сегодня.Разница, однако, заключалась в том, что я использовал функцию вставки, где вышеупомянутый человек не указывает это.Мне нужно было сделать так, чтобы моя хранимая процедура вставки возвращала SCOPE_IDENTITY () и использовала привязку результата для возвращенного идентификатора.

Исправлена ​​ошибка.

1 голос
/ 10 июня 2011

Попробуйте использовать метод обновления после сохранения изменений, это было задокументировано в MSDN

"Чтобы гарантировать, что объекты на клиенте были обновлены с помощью логики на стороне источника данных, вы можете вызвать метод Refresh со значением StoreWins после вызова SaveChanges."

http://msdn.microsoft.com/en-us/library/bb336792.aspx

Хотя я чувствую, что, по мнению @Craig, также может сработать.

...