Странное поведение EF
От: senglory  
Дата: 19.02.21 06:48
Оценка:
Вот есть такой код:

[Table("IncomingTransactions",Schema ="demo")]
public class Transactions
{
    [Key]
    [Column("tranId")]
    [MaxLength(12)]
    public string TranID { get; set; }


public class FamilyTeamSvcDbContext : DbContext
{
    public DbSet<Transactions> Transactions { get; set; }


foreach (var tr in lstTrans)
{
    var transactionAreadyInDB = ctx.Transactions
        .Where(x => x.TranID == tr.TranID ).Any();
    if (transactionAreadyInDB)
    {
        continue;
    }
    ctx.Transactions.Add(tr);


В коллекцию lstTrans пришло несколько транзакций, ранее не находившихся в базе и при этом с одинаковым TranID. В итоге, на последней строке я ловлю воттакую ошибку:

System.InvalidOperationException: The instance of entity type 'Transactions' cannot be tracked because another instance with the same key value for {'TranID'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Add(TEntity entity)



Я могу к ctx.Transactions добавить AsNoTracking — пофигу, ошибка остается. Как ее устранить? Разумеется, повлиять на содержимое lstTrans я не могу.
ef core .net
Re: Странное поведение EF
От: varenikAA  
Дата: 19.02.21 07:01
Оценка:
Здравствуйте, senglory, Вы писали:

S>Я могу к ctx.Transactions добавить AsNoTracking — пофигу, ошибка остается. Как ее устранить? Разумеется, повлиять на содержимое lstTrans я не могу.


AsNoTracking()
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Странное поведение EF
От: senglory  
Дата: 19.02.21 07:08
Оценка:
S>>Я могу к ctx.Transactions добавить AsNoTracking — пофигу, ошибка остается. Как ее устранить? Разумеется, повлиять на содержимое lstTrans я не могу.

AA>AsNoTracking()


Так я же говорю — пофигу, ошибка остается той же.
Re[3]: Странное поведение EF
От: varenikAA  
Дата: 19.02.21 07:33
Оценка:
Здравствуйте, senglory, Вы писали:

S>>>Я могу к ctx.Transactions добавить AsNoTracking — пофигу, ошибка остается. Как ее устранить? Разумеется, повлиять на содержимое lstTrans я не могу.


AA>>AsNoTracking()


S>Так я же говорю — пофигу, ошибка остается той же.


Ясно, тогда так:
            migrationBuilder.Sql("update плохая таблица");
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Странное поведение EF
От: fmiracle  
Дата: 19.02.21 08:30
Оценка:
Здравствуйте, senglory, Вы писали:

S>В коллекцию lstTrans пришло несколько транзакций, ранее не находившихся в базе и при этом с одинаковым TranID.


Но это поле у тебя помечено как [Key], а значит должно быть уникальным.

Либо убрать ключ вообще, либо, если надо импортировать какие-то внешние сущности, то для них стоит делать другой класс, где это поле неключевое и затем трансформировать одно в другое с назначением нового, уникального TranID
Re: Странное поведение EF
От: Danchik Украина  
Дата: 19.02.21 18:29
Оценка: 10 (2)
Здравствуйте, senglory, Вы писали:

[Skip]

S>Я могу к ctx.Transactions добавить AsNoTracking — пофигу, ошибка остается. Как ее устранить? Разумеется, повлиять на содержимое lstTrans я не могу.


Ух уж эти EF филы.
Разъясняю по пальцам. Скорее всего ты этот контекст держишь слишком долго, например синглтоном и там уже есть объект с таким ключом. Кстати плохая практика. Чем дольше программа работает — тем она тормознутей. Пересоздавай контекст на каждый отдельный переосмысленный чих.

Но и здесь есть выход. Надо не Any а Find

foreach (var tr in lstTrans)
{
    var transactionAreadyInDB = ctx.Transactions.Find(tr.TranID);
    if (transactionAreadyInDB != null)
    {
        continue;
    }
    ctx.Transactions.Add(tr);
}


Удачи тебе в убийстве базы.
Re: Странное поведение EF
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.02.21 08:49
Оценка:
Здравствуйте, senglory, Вы писали:


S>В коллекцию lstTrans пришло несколько транзакций, ранее не находившихся в базе и при этом с одинаковым TranID. В итоге, на последней строке я ловлю воттакую ошибку:///

Ты пытаешься добавить несколько разных записей с одинаковым ключом. Ты какое поведение ожидаешь?
Re[2]: Странное поведение EF
От: senglory  
Дата: 20.02.21 09:14
Оценка:
G>Ты какое поведение ожидаешь?

Я ожидаю что это:

.Where(x => x.TranID == tr.TranID ).Any();


обнаружит присутствие уже добавленной записи с таким ключом.
Re[3]: Странное поведение EF
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.02.21 11:37
Оценка: 6 (1)
Здравствуйте, senglory, Вы писали:

G>>Ты какое поведение ожидаешь?


S>Я ожидаю что это:


S>
S>.Where(x => x.TranID == tr.TranID ).Any();
S>


S>обнаружит присутствие уже добавленной записи с таким ключом.


Не обнаружит. Этот кож сделает запрос в базу, а в базе таких ключей нет еще.
Нужо или find использовать, или заранее дубли отфильтровать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.