C #, сущность, автоинкремент - PullRequest
24 голосов
/ 06 июля 2010

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

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

Что я делаю не так? Как мне настроить EF или саму базу данных SQL?

Ответы [ 5 ]

37 голосов
/ 07 июля 2010

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

Здесь это объясняется лучше: Автономер с Entity Framework

2 голосов
/ 06 июля 2010

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

db.AddToUserSet(user);//Added to EF entity collection
db.SaveChanges();//INSERT executed in db, Identity set and incremented.
1 голос
/ 06 июля 2010

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

1 голос
/ 06 июля 2010

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

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

0 голосов
/ 18 декабря 2014

У меня были похожие проблемы, которые возникали в 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;
} 

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...