我在使用EF Core 3.1时遇到问题。直到最近都可以使用的代码。我有在DbContext上调用SaveChanges之前调用的此方法:
private void SetProps<TEntity>(TEntity dbEntity, EntityState newState)
where TEntity : class, new()
{
var entry = this.dbContext.Entry(dbEntity);
...
if (dbEntity is IDbEntityBase dbEntityBase)
{
var baseEntry = this.dbContext.Entry(dbEntityBase);
if (newState == EntityState.Added)
{
baseEntry.Property(t => t.Id).CurrentValue = Guid.NewGuid();
}
}
}
遗漏了大量代码以便于阅读,因此任何设计更改都将难以完成。
我遇到的问题是致电baseEntry.Property(t => t.Id).CurrentValue = Guid.NewGuid();
。调用该代码时,EF抛出异常'this' type cannot be an interface itself.
。
IDbEntity是所有实体类都实现的一些基本接口(它具有一些公共属性)。
EF调用堆栈如下所示:
System.ArgumentException: 'this' type cannot be an interface itself.
at System.RuntimeTypeHandle.VerifyInterfaceIsImplemented(RuntimeTypeHandle interfaceHandle)
at System.RuntimeType.GetInterfaceMap(Type ifaceType)
at System.Reflection.RuntimeReflectionExtensions.GetRuntimeInterfaceMap(TypeInfo typeInfo, Type interfaceType)
at Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.GetPropertyAccess(LambdaExpression propertyAccessExpression)
at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1.Property[TProperty](Expression`1 propertyExpression)
at InDocEdge.Sap.Database.EfContext.SapDbContext.ProcessBeforeSaveChangesData() in C:\MyCode\MyDbContext.cs:line 2
at InDocEdge.Sap.Database.EfContext.SapDbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) in C:\MyCode\MyDbContext.cs:line 1
该代码直到最近才起作用,但是现在(以我的理解),EF不满意我为Entry方法提供接口类型,我认为这是可能的。
有谁知道可能出什么问题或如何解决此问题?
接口类型没有EntityEntry这样的东西。它必须是一个实体类型。并且EntityEntry<TEntity>.Property
需要找到实体类型属性,而不是接口属性(它们在概念上可能实际上不同)。
但是在通常情况下,您的Entity的属性实现IDbEntityBase.Id
也将称为Id
,您可以将该名称传递给entry.Property(string)
,例如:
private void SetProps<TEntity>(TEntity dbEntity, EntityState newState) where TEntity : class, new()
{
var entry = Entry(dbEntity);
if (dbEntity is IDbEntityBase)
{
if (newState == EntityState.Added)
{
entry.Property(nameof(IDbEntityBase.Id)).CurrentValue = Guid.NewGuid();
}
}
}
或者,由于仅设置了EntityEntry.CurrentValue
,因此可以直接通过Entity对象,通过IDbEntityBase引用而不是EntityEntry对其进行设置。例如:
private void SetProps<TEntity>(TEntity dbEntity, EntityState newState) where TEntity : class, new()
{
if (dbEntity is IDbEntityBase dbEntityBase)
{
if (newState == EntityState.Added)
{
dbEntityBase.Id = Guid.NewGuid();
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句