gpt4 book ai didi

c# - 如何使用内存数据库中的Entity Framework核心自动递增列?

转载 作者:行者123 更新时间:2023-12-03 15:04:07 28 4
gpt4 key购买 nike

我正在使用这样的内存EF Core数据库:

            var options = new DbContextOptionsBuilder<DmpContext>()
.UseInMemoryDatabase("test")
.Options;

var context = new CustomContext(options);

我正在使用仿冒品添加一些随机数据。
            var resources = new Faker<Resource>()
.RuleFor(x => x.Name, x => x.Name.FullName())
.Generate(20);

在此资源集合中,所有id仍为零。

当我执行AddRange时,我希望生成ID:
                context.Resources.AddRange(resources);
context.SaveChangesAsync();

但是它们不是生成的。

System.AggregateException : One or more errors occurred. (The instance of entity type 'Resource' cannot be tracked because another instance with the same key value for {'ResourceId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.



所以我想,然后让我直接设置它们,然后自己创建一个自动增量机制。那行得通。

但是,当我随后尝试测试我的 Add方法(这些方法插入记录)时。我无法在这些方法中设置ID,因为该ID甚至不在界面中。再次,我希望EF自动生成ID,但是它会尝试插入ID 1(由于我已经生成了ID 1直到20,所以已经插入了ID 1)。

有人知道如何告诉内存数据库中的EF核心始终自动递增其 key 吗?

最佳答案

在内存数据库中,EF无法检测到实体的身份属性,我已对其进行了覆盖

InMemoryIntegerValueGenerator



用于处理此问题的类。以下代码显示了如何执行此操作。
public abstract class BaseEntity
{
public long ID { get; set; }
}

public class RoleResource : BaseEntity
{
public long RoleID { get; set; }
public long ResourceID { get; set; }
}

public class CASDbContext : DbContext
{
public CASDbContext(DbContextOptions options) : base(options) { }
public DbSet<RoleResource> RoleResources { get; set; }
}


public class CustomInMemoryIntegerValueGenerator<TEntity>
: InMemoryIntegerValueGenerator<long> where TEntity : BaseEntity
{
private long _current;
public override bool GeneratesTemporaryValues => false;
public override long Next(EntityEntry entry)
{
long result;
if (entry.Properties.Any(x => x.Metadata.ValueGenerated == ValueGenerated.OnAdd))
{
_current = entry.Context.Set<TEntity>()
.Select(x => x.ID)
.DefaultIfEmpty(0)
.Max(x => x);
var res = Interlocked.Increment(ref _current);
result = res;
}
else
result = base.Next(entry);
return result;
}
}
public class InMemoryDbContext : CASDbContext
{
public InMemoryDbContext(DbContextOptions options) : base(options) { }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<RoleResource>(rr =>
{
rr.HasKey(e => e.ID);
rr.Property(e => e.ID)
.HasValueGenerator<CustomInMemoryIntegerValueGenerator<RoleResource>>();
});
}
}

[TestInitialize]
public void Setup()
{
srvCollection.AddScoped<SeedData>();
srvCollection.AddTransient<CASDbContext, InMemoryDbContext>();
srvCollection.AddDbContext<InMemoryDbContext>(x =>
x.UseInMemoryDatabase("In-Memory")).AddEntityFrameworkInMemoryDatabase();

_serviceProvider = srvCollection.BuildServiceProvider();

}
/* The packages version
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.6" />
*/

关于c# - 如何使用内存数据库中的Entity Framework核心自动递增列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47754939/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com