EF Core меняет идентификатор объекта при добавлении. Объект невозможно отследить, поскольку уже отслеживается другой экзC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 EF Core меняет идентификатор объекта при добавлении. Объект невозможно отследить, поскольку уже отслеживается другой экз

Сообщение Anonymous »

Я работаю над библиотекой для генерации случайных данных для реляционных баз данных. Я использую отражение для добавления экземпляров объекта в свой DbContext, поскольку не могу явно указать тип экземпляра.

Код: Выделить всё

public class EntityAdder where TDbContext : DbContext
{
private readonly TDbContext _dbContext;
private readonly MyOptions _options;

public EntityAdder(TDbContext dbContext,
MyOptionsProvider optionsProvider)
{
_dbContext = dbContext;
_options = optionsProvider.GetOptions();
}

public async Task AddEntities(Dictionary entities)
{
var dbSets = typeof(TDbContext)
.GetProperties()
.Where(x => x.PropertyType.IsGenericType)
.Select(x => new DbSetInfo
{
DbSet = x.GetGetMethod()!.Invoke(_dbContext, [])!,
DbSetProperty = x,
AddMethod = x.PropertyType.GetMethod("Add")!
})
.ToList();

foreach (var (entity, pool) in entities)
{
var dbSet = dbSets.Single(x => x.DbSetProperty.PropertyType.GetGenericArguments()[0] == entity.EntityType);

if (_options.OverrideExistingData)
{
clearDbSet(dbSet);
}

foreach (var entityObject in pool)
{
dbSet.AddMethod.Invoke(dbSet.DbSet, [entityObject]);
}
}

await _dbContext.SaveChangesAsync();
}

private void clearDbSet(DbSetInfo dbSet)
{
MethodInfo removeRangeMethod = dbSet.DbSetProperty.PropertyType
.GetMethods()
.Where(x => x.Name == "RemoveRange")
.ElementAt(1);
removeRangeMethod.Invoke(dbSet.DbSet, [dbSet.DbSet]);
}

class DbSetInfo
{
public object DbSet { get; set; }
public PropertyInfo DbSetProperty { get; set; }
public MethodInfo AddMethod { get; set; }
}
}
Объекты:

Код: Выделить всё

public class TestEntity1
{
public int ID { get; set; }
public int Value { get; set; }
public string Value2 { get; set; }
public bool Value3 { get; set; }
public TestEntity2? Entity2 { get; set; }
}

public class TestEntity2
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string ID { get; set; }
public string Value { get; set; }
public string Value2 { get; set; }
public TestEntity1? Entity1 { get; set; }
public int? Entity1ID { get; set; }
}

Код: Выделить всё

DbContext:
public class TestContext : DbContext
{
public TestContext() { }
public TestContext(DbContextOptions options) : base(options) { }
public DbSet Entity1 { get; set; }
public DbSet Entity2 { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
if (builder.IsConfigured) return;

builder.EnableSensitiveDataLogging();

builder.UseInMemoryDatabase("TestDatabase");
}

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity()
.HasKey(e => e.ID);
builder.Entity()
.HasKey(e => e.ID);

builder.Entity()
.HasOne(e => e.Entity2)
.WithOne(e => e.Entity1)
.HasForeignKey(e => e.Entity1ID);
}
}

Код: Выделить всё

EntityInfoКласс 
содержит некоторую полезную информацию о сущности, такую ​​как тип, количество экземпляров и т. д., которая, на мой взгляд, не имеет отношения к проблеме.
Идентификатор первого экземпляра в значение пула равно 0, но при попытке добавить его в dbSet оно внезапно меняется на 1. Затем при добавлении следующего экземпляра с идентификатором 1 выдается исключение, поскольку идентификатор первого экземпляра был изменен на 1:

Экземпляр типа сущности «TestEntity1» невозможно отследить, поскольку другой экземпляр со значением ключа «{ID: 1}» уже отслеживается. При присоединении существующих объектов убедитесь, что присоединен только один экземпляр объекта с заданным значением ключа.

Первый шаг итерации:
Изображение

После добавления:
Изображение

Почему это происходит и как это исправить?

Подробнее здесь: https://stackoverflow.com/questions/785 ... another-in
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»