从 .NET Framework 4.52 迁移到 .NET Core 后的通用存储库问题
Generic repository issue after migrating from .NET Framework 4.52 to .NET Core
我正在将遗留代码从 .NET Framework 4.52 迁移到 netstandard1.4(FWIW,我也正在从 EF 6 迁移到 EF Core)。
我的问题源于 IDbSet<T>
当前未在 EF Core 中实现。
在 EF 6 中,IDbSet<Plugin>.Add(entity)
returns 插件类型的代理。
在 EF Core 中,context.Set<Plugin>.Add(entity)
returns{Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}。
在 EF Core 中从 Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin] 转换为 Dna.NetCore.Core.BLL.Entities.Plugins.Plugin 时出现以下异常。
问 - 我该如何投射这个?
EF 6 RepositoryBase.cs
public abstract class RepositoryBase<T, U>
where T : class
where U : DbContext, new()
{
private U _dataContext;
private readonly IDbSet<T> _dbset;
public virtual T Add(T entity)
{
object dao = _dbset.Add(entity);
return dao as T;
}
}
EF 核心RepositoryBase.cs
public abstract class RepositoryBase<T>
where T : class
{
//private readonly IDbSet<T> _dbset; // IDbSet is not implemented in .NET Core 1.0.1
private readonly Microsoft.EntityFrameworkCore.DbSet<T> _dbset;
private readonly CoreEFContext _context;
protected RepositoryBase(CoreEFContext context)
{
_context = context;
_dbset = _context.Set<T>();
}
public virtual T Add(T entity, out CustomMessage customMessage)
{
object dao = _dbset.Add(entity);
return dao as T;
}
}
repository 在 GitHub 中可用。
在 RepositoryBase.cs 第 64 行:
当地人Window:
this._dbset.Results View = "Enumeration yielded no results"
this._context.ChangeTracker.Non-Public
members.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure.Instance.Entries[0]
= does contain the entity
立即Window:
(Dna.NetCore.Core.BLL.Entities.Plugins.Plugin)道
'(Dna.NetCore.Core.BLL.Entities.Plugins.Plugin)dao' threw an exception of type 'System.InvalidCastException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2147467262
HelpLink: null
InnerException: null
Message: "Specified cast is not valid."
Source: null
StackTrace: null
dao 作为 T
'dao as T' threw an exception of type 'System.NullReferenceException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2147467261
HelpLink: null
InnerException: null
Message: "Object reference not set to an instance of an object."
Source: null
StackTrace: null
dao.GetType()
{Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}
Assembly: {Microsoft.EntityFrameworkCore, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60}
AssemblyQualifiedName: "Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry
1[[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin, Dna.NetCore.Core.BLL, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null]], Microsoft.EntityFrameworkCore, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"
Attributes: Public | BeforeFieldInit
BaseType: {Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry}
ContainsGenericParameters: false
CustomAttributes: Count = 0
DeclaredConstructors: {System.Reflection.ConstructorInfo1}
DeclaredEvents: {System.Reflection.EventInfo[0]}
DeclaredFields: {System.Reflection.FieldInfo[0]}
DeclaredMembers: {System.Reflection.MemberInfo[5]}
DeclaredMethods: {System.Reflection.MethodInfo[3]}
DeclaredNestedTypes: {System.Reflection.TypeInfo.d__23}
DeclaredProperties: {System.Reflection.PropertyInfo1}
DeclaringMethod: '((System.RuntimeType)(dao.GetType())).DeclaringMethod' threw an exception of type 'System.InvalidOperationException'
DeclaringType: null
FullName: "Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry1[[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin, Dna.NetCore.Core.BLL, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null]]"
GUID: {bbf992a5-ba4d-3ab3-8a66-fa5a37a909ae}
GenericParameterAttributes: '((System.RuntimeType)(dao.GetType())).GenericParameterAttributes' threw an exception of type 'System.InvalidOperationException'
GenericParameterPosition: '((System.RuntimeType)(dao.GetType())).GenericParameterPosition' threw an exception of type 'System.InvalidOperationException'
GenericTypeArguments: {System.Type[1]}
GenericTypeParameters: {System.Type[0]}
HasElementType: false
ImplementedInterfaces: {System.Type[1]}
IsAbstract: false
IsAnsiClass: true
IsArray: false
IsAutoClass: false
IsAutoLayout: true
IsByRef: false
IsCOMObject: false
IsClass: true
IsConstructedGenericType: true
IsEnum: false
IsExplicitLayout: false
IsGenericParameter: false
IsGenericType: true
IsGenericTypeDefinition: false
IsImport: false
IsInterface: false
IsLayoutSequential: false
IsMarshalByRef: false
IsNested: false
IsNestedAssembly: false
IsNestedFamANDAssem: false
IsNestedFamORAssem: false
IsNestedFamily: false
IsNestedPrivate: false
IsNestedPublic: false
IsNotPublic: false
IsPointer: false
IsPrimitive: false
IsPublic: true
IsSealed: false
IsSecurityCritical: true
IsSecuritySafeCritical: false
IsSecurityTransparent: false
IsSerializable: false
IsSpecialName: false
IsUnicodeClass: false
IsValueType: false
IsVisible: true
MemberType: TypeInfo
MetadataToken: 33554824
Module (System.Reflection.MemberInfo): {Microsoft.EntityFrameworkCore.dll}
Module: {Microsoft.EntityFrameworkCore.dll}
Name: "EntityEntry
1"
Namespace: "Microsoft.EntityFrameworkCore.ChangeTracking"
ReflectedType: null
StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
TypeHandle: {System.RuntimeTypeHandle}
TypeInitializer: null
UnderlyingSystemType: {Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}
Plugin_UpdateHandler.cs 第 56 行 returns:
Dna.NetCore.Core.DAL.EFCore.Repositories.RepositoryBase.Add returned null Dna.NetCore.Core.BLL.Entities.Plugins.Plugin
您应该能够通过 DbSet 上的 Entity
属性 访问该实体。您可以直接 return 参数或访问 EntityEntry<T>
对象来让 ER Core 完全控制要做什么:
public virtual T Add(T entity, out CustomMessage customMessage)
{
var entry = _dbset.Add<T>(entity);
...
return entry.Entity;
}
请注意,目前 EF Core 没有 EF 6 的代理功能。
我正在将遗留代码从 .NET Framework 4.52 迁移到 netstandard1.4(FWIW,我也正在从 EF 6 迁移到 EF Core)。
我的问题源于 IDbSet<T>
当前未在 EF Core 中实现。
在 EF 6 中,IDbSet<Plugin>.Add(entity)
returns 插件类型的代理。
在 EF Core 中,context.Set<Plugin>.Add(entity)
returns{Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}。
在 EF Core 中从 Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin] 转换为 Dna.NetCore.Core.BLL.Entities.Plugins.Plugin 时出现以下异常。
问 - 我该如何投射这个?
EF 6 RepositoryBase.cs
public abstract class RepositoryBase<T, U>
where T : class
where U : DbContext, new()
{
private U _dataContext;
private readonly IDbSet<T> _dbset;
public virtual T Add(T entity)
{
object dao = _dbset.Add(entity);
return dao as T;
}
}
EF 核心RepositoryBase.cs
public abstract class RepositoryBase<T>
where T : class
{
//private readonly IDbSet<T> _dbset; // IDbSet is not implemented in .NET Core 1.0.1
private readonly Microsoft.EntityFrameworkCore.DbSet<T> _dbset;
private readonly CoreEFContext _context;
protected RepositoryBase(CoreEFContext context)
{
_context = context;
_dbset = _context.Set<T>();
}
public virtual T Add(T entity, out CustomMessage customMessage)
{
object dao = _dbset.Add(entity);
return dao as T;
}
}
repository 在 GitHub 中可用。
在 RepositoryBase.cs 第 64 行:
当地人Window:
this._dbset.Results View = "Enumeration yielded no results"
this._context.ChangeTracker.Non-Public members.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure.Instance.Entries[0] = does contain the entity
立即Window:
(Dna.NetCore.Core.BLL.Entities.Plugins.Plugin)道
'(Dna.NetCore.Core.BLL.Entities.Plugins.Plugin)dao' threw an exception of type 'System.InvalidCastException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2147467262
HelpLink: null
InnerException: null
Message: "Specified cast is not valid."
Source: null
StackTrace: null
dao 作为 T
'dao as T' threw an exception of type 'System.NullReferenceException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2147467261
HelpLink: null
InnerException: null
Message: "Object reference not set to an instance of an object."
Source: null
StackTrace: null
dao.GetType()
{Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry
1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}
1[[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin, Dna.NetCore.Core.BLL, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null]], Microsoft.EntityFrameworkCore, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"
Assembly: {Microsoft.EntityFrameworkCore, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60}
AssemblyQualifiedName: "Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry
Attributes: Public | BeforeFieldInit
BaseType: {Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry}
ContainsGenericParameters: false
CustomAttributes: Count = 0
DeclaredConstructors: {System.Reflection.ConstructorInfo1}
DeclaredEvents: {System.Reflection.EventInfo[0]}
DeclaredFields: {System.Reflection.FieldInfo[0]}
DeclaredMembers: {System.Reflection.MemberInfo[5]}
DeclaredMethods: {System.Reflection.MethodInfo[3]}
DeclaredNestedTypes: {System.Reflection.TypeInfo.d__23}
DeclaredProperties: {System.Reflection.PropertyInfo1}
DeclaringMethod: '((System.RuntimeType)(dao.GetType())).DeclaringMethod' threw an exception of type 'System.InvalidOperationException'
DeclaringType: null
FullName: "Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry1[[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin, Dna.NetCore.Core.BLL, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null]]"
1"
GUID: {bbf992a5-ba4d-3ab3-8a66-fa5a37a909ae}
GenericParameterAttributes: '((System.RuntimeType)(dao.GetType())).GenericParameterAttributes' threw an exception of type 'System.InvalidOperationException'
GenericParameterPosition: '((System.RuntimeType)(dao.GetType())).GenericParameterPosition' threw an exception of type 'System.InvalidOperationException'
GenericTypeArguments: {System.Type[1]}
GenericTypeParameters: {System.Type[0]}
HasElementType: false
ImplementedInterfaces: {System.Type[1]}
IsAbstract: false
IsAnsiClass: true
IsArray: false
IsAutoClass: false
IsAutoLayout: true
IsByRef: false
IsCOMObject: false
IsClass: true
IsConstructedGenericType: true
IsEnum: false
IsExplicitLayout: false
IsGenericParameter: false
IsGenericType: true
IsGenericTypeDefinition: false
IsImport: false
IsInterface: false
IsLayoutSequential: false
IsMarshalByRef: false
IsNested: false
IsNestedAssembly: false
IsNestedFamANDAssem: false
IsNestedFamORAssem: false
IsNestedFamily: false
IsNestedPrivate: false
IsNestedPublic: false
IsNotPublic: false
IsPointer: false
IsPrimitive: false
IsPublic: true
IsSealed: false
IsSecurityCritical: true
IsSecuritySafeCritical: false
IsSecurityTransparent: false
IsSerializable: false
IsSpecialName: false
IsUnicodeClass: false
IsValueType: false
IsVisible: true
MemberType: TypeInfo
MetadataToken: 33554824
Module (System.Reflection.MemberInfo): {Microsoft.EntityFrameworkCore.dll}
Module: {Microsoft.EntityFrameworkCore.dll}
Name: "EntityEntry
Namespace: "Microsoft.EntityFrameworkCore.ChangeTracking"
ReflectedType: null
StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
TypeHandle: {System.RuntimeTypeHandle}
TypeInitializer: null
UnderlyingSystemType: {Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}
Plugin_UpdateHandler.cs 第 56 行 returns:
Dna.NetCore.Core.DAL.EFCore.Repositories.RepositoryBase.Add returned null Dna.NetCore.Core.BLL.Entities.Plugins.Plugin
您应该能够通过 DbSet 上的 Entity
属性 访问该实体。您可以直接 return 参数或访问 EntityEntry<T>
对象来让 ER Core 完全控制要做什么:
public virtual T Add(T entity, out CustomMessage customMessage)
{
var entry = _dbset.Add<T>(entity);
...
return entry.Entity;
}
请注意,目前 EF Core 没有 EF 6 的代理功能。