2010-07-06 5 views
23

Я учусь Entity Framework под VC# 2010C#, рамки сущность, автоматическое приращение

Я создал простую таблицу для целей обучения, один из полей «идентификатор» целочисленный тип, личность устанавливается истина , Я создал модель данных сущности из этой таблицы и связал ее с dataGridView. Проблема в том, что он не увеличивается автоматически - каждая вставленная строка хочет быть id = 0 (что невозможно, конечно, поскольку идентификатор должен быть уникальным)

Что я делаю неправильно? Как мне настроить EF или SQL db?

ответ

35

Проверьте в своей модели EDMX, что для атрибута StoreGeneratedPattern поля autoincrement установлено значение «Identity». Таким образом, EF знает, что автоответчики обрабатываются БД.

Вот это объясняется лучше: Autonumber with Entity Framework

+0

Да, как правило, из созданных VS2010 фрагментов вам нужно будет установить значение StoreGenerated в верхнем большом блоке xml. Вы получаете несколько первичных ключей, потому что, если вы не измените это, EF генерирует идентификатор для вас, как 0. – Rangoric

+5

Это безумие, что они еще не исправили эту вездесущую ошибку. Это версия 4, приходите в команду EF !! – arviman

+1

Много раз люди забывают отмечать столбец значением Identity и auto increment. EF делает это из БД. – arviman

1

Убедитесь, что вы сохраняете свои объекты обратно в базу данных, прежде чем пытаться прочитать значение с автоматическим инкрементным идентификатором.

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

+2

проблема в том, что при вызове SaveChanges (после добавления нескольких строк) он бросает исключение о дублируется первичного ключа ... – migajek

+0

@vic - Интересно. Вы уверены, что он не работает на вставке для таблицы с автоматическим увеличением? –

1

Да. LINQ to SQL ведет себя одинаково. Идентификатор не будет установлен до тех пор, пока он не будет сохранен в базе данных. Пока вы это сделаете, все идентификаторы будут равны нулю (как вы уже видели).

2

Идентичность не установлен и увеличивается только путем добавления к набору сущностей ... Объект не фактически сохранен в БД, пока не называют context.SaveChanges() ...

db.AddToUserSet(user);//Added to EF entity collection 
db.SaveChanges();//INSERT executed in db, Identity set and incremented. 
+6

проблема заключается в том, что при вызове SaveChanges (после добавления нескольких строк) он выдает исключение из дублированного первичного ключа ... – migajek

0

Я имел аналогичные проблемы, которые произошли в EF6 (сделал работу в EF4 без операций, EF 4 используются неявные операции с правом сферы).

Просто создание нового объекта и его сохранение не помогли в моем случае (см. Комментарии к другим ответам, у них были аналогичные проблемы с использованием dc.SaveChanges() только для автоматического обновления).

Рассмотрим следующий код (CustomerId первичный ключ с автоматическим приращением):

public void UpdateCustomer(string strCustomerName, string strDescription) 
{ 
    using (var transaction = CreateTransactionScope()) 
    { 
    MyCustomer tbl=null; 
    Func<MyCustomer, bool> selectByName=(i => i.CustomerName.Equals(strCustomerName)); 
    var doesRecordExistAlready = dc.MyCustomers.Any(selectByName); 
    if (doesRecordExistAlready) 
    { 
     // Updating 
     tbl=dc.MyCustomers.Where(selectByName).FirstOrDefault();   
     tbl.Description=strDescription; 
    } 
    else 
    { 
     // Inserting 
     tbl=new MyCustomer(); 
     var maxItem= 
      dc.MyCustomers.OrderByDescending(i => i.CustomerId).FirstOrDefault(); 
     var newID = maxItem==null ? 1 : maxItem.CustomerId+1; 
     tbl.CustomerId=newID; 
     tbl.CustomerName=strCustomerName; 
     tbl.Description=strDescription; 
     dc.MyCustomers.AddObject(tbl);  
    } 
    dc.SaveChanges(); // save all changes consistently   
    transaction.Complete(); // commit 
    } 
} 

И вспомогательную функцию для создания контекста правой сделки является:

// creates the right transaction scope 
public static System.Transactions.TransactionScope CreateTransactionScope() 
    // needs to add ref: System.Transactions 
{ 
    var transactionOptions = new TransactionOptions 
    { 
     IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, 
     Timeout = new TimeSpan(0,0,10,0,0) //assume 10 min is the timeout time 
    }; 
    var scopeOption=TransactionScopeOption.RequiresNew; 
    var scope = new System.Transactions.TransactionScope(scopeOption, 
       transactionOptions); 
    return scope; 
} 

Хитрость здесь , чтобы разрешить чтение uncommitted - следовательно, вы можете запросить max ID и добавить 1 к id. То, чего я не смог достичь, - позволить SQL-серверу генерировать идентификатор автоматически, потому что EF позволяет мне не пропускать CustomerId при создании.

Чтобы узнать больше о рамках сделки, look here.

Смежные вопросы