С#, структура сущности, автоматическое увеличение

Я изучаю Entity Framework под VС# 2010.

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

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

Ответ 1

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

Здесь это объясняется лучше: Автономный номер с инфраструктурой Entity

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

У меня были аналогичные проблемы, которые произошли в 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 при создании.

Чтобы узнать больше о области транзакций, посмотреть здесь.