从 .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 的代理功能。