В Entity Framework получение значения столбца идентификатора после вставки
Я использую EF4. Я хочу вставить новый MyObject в базу данных. MyObject имеет два поля:
Id: int (Identity) и Имя: строка
Как я видел в документации 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
}
обновление:
это происходит в одном из моих объектов, и другие работают нормально. Кстати, я проверено, и столбец DB является идентификатором, а StoreGeneratedPattern имеет значение Identity. Вот 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 ответов
в этом случае вы EF модель, вероятно, не в курсе - EF должен автоматически получить ваш новый идентификатор из базы данных. Попробуйте обновить модель EF.
свойства столбца идентификаторов должны выглядеть следующим образом в модели EDMX:
Если вы используете Oracle Entity Framework 4 Provider, как и я, из ODP.NET, есть ошибка в Designer. Просто выбор значения идентификатора в раскрывающемся списке не будет делать. Он будет аннотировать концептуальное свойство в концептуальной модели с помощью
аннотация: 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, потому что я ее не использовал.
Это должно "просто работать."Убедитесь, что столбец DB на самом деле IDENTITY
и StoreGeneratedPattern
имеет значение Identity в EDMX.
вау! это был кошмар, но в конце концов я решил его, хотя и не понимал, в чем проблема. Возможно, это поможет кому-то с той же проблемой.
- сгенерировать скрипт создания таблицы и ее данных.
- удалить таблицу.
- запустить скрипт.
Если вы используете Linq для сущностей и получаете эту ошибку, даже если вы следовали советам marc_s (которые действительно хороши), вы должны посмотреть на свои entites непосредственно в 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" тоже требуется.
попробуйте использовать метод обновления после сохранения изменений, он был задокументирован в MSDN
" чтобы гарантировать, что объекты на клиенте были обновлены логикой на стороне источника данных, можно вызвать метод Refresh со значением StoreWins после вызова SaveChanges."
http://msdn.microsoft.com/en-us/library/bb336792.aspx
хотя я чувствую, что @ Craig предложил также может работать.
Я столкнулся с этим сегодня. Разница в том, что я использовал функцию вставки, где вышеупомянутый человек не указывает это. Мне нужно было сделать так, чтобы хранимая процедура insert возвращала SCOPE_IDENTITY() и использовала привязку результата для возвращаемого идентификатора.
Исправлена ошибка.