【问题标题】:Generic repository issue after migrating from .NET Framework 4.52 to .NET Core从 .NET Framework 4.52 迁移到 .NET Core 后的通用存储库问题
【发布时间】:2016-10-22 21:02:06
【问题描述】:

我正在将旧代码从 .NET Framework 4.52 迁移到 netstandard1.4(FWIW,我也在从 EF 6 迁移到 EF Core)。

我的问题源于 IDbSet<T> 当前未在 EF Core 中实现。

在 EF 6 中,IDbSet<Plugin>.Add(entity) 返回 Plugin 类型的代理。

在 EF Core 中,context.Set<Plugin>.Add(entity) 返回 {Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}。

从 Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin] 投射到 Dna.NetCore.Core.BLL.Entities.Plugins 时出现以下异常。 EF Core 中的插件。

问 - 我怎样才能投射这个?

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 Core 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 行:

本地窗口:

this._dbset.Results View = “枚举未产生任何结果”
this._context.ChangeTracker.Non-Public members.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure.Instance.Entries[0] = 确实包含实体

立即窗口:

(Dna.NetCore.Core.BLL.Entities.Plugins.Plugin)dao

'(Dna.NetCore.Core.BLL.Entities.Plugins.Plugin)dao' 引发了“System.InvalidCastException”类型的异常
数据:{System.Collections.ListDictionaryInternal}
H结果:-2147467262
帮助链接:空
内部异常:null
消息:“指定的演员表无效。”
来源:空
堆栈跟踪:空

道为T

“dao as T”引发了“System.NullReferenceException”类型的异常
数据:{System.Collections.ListDictionaryInternal}
H结果:-2147467261
帮助链接:空
内部异常: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,版本=1.0.1.0,文化=中性,PublicKeyToken=adb9793829ddae60"
属性:公开 | BeforeFieldInit
基本类型:{Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry}
包含通用参数:false
自定义属性:计数 = 0
声明的构造函数:{System.Reflection.ConstructorInfo1}
声明事件:{System.Reflection.EventInfo[0]}
声明字段:{System.Reflection.FieldInfo[0]}
DeclaredMembers: {System.Reflection.MemberInfo[5]}
声明的方法:{System.Reflection.MethodInfo[3]}
声明的嵌套类型:{System.Reflection.TypeInfo.d__23}
声明的属性:{System.Reflection.PropertyInfo1}
DeclaringMethod: '((System.RuntimeType)(dao.GetType())).DeclaringMethod' 引发了类型为 'System.InvalidOperationException' 的异常
声明类型:空
全名:“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”
命名空间:“Microsoft.EntityFrameworkCore.ChangeTracking”
反射类型:空
StructLayoutAttribute:{System.Runtime.InteropServices.StructLayoutAttribute}
类型句柄:{System.RuntimeTypeHandle}
类型初始化器:空
底层系统类型:{Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry`1[Dna.NetCore.Core.BLL.Entities.Plugins.Plugin]}

Plugin_UpdateHandler.cs 第 56 行返回:

Dna.NetCore.Core.DAL.EFCore.Repositories.RepositoryBase.添加返回的 null Dna.NetCore.Core.BLL.Entities.Plugins.Plugin

【问题讨论】:

  • EF 6 to EF Core 这就是原因。您应该将此代码减少 95%。
  • 请停止针对 .NET Standard 1.5 和 1.6,blogs.msdn.microsoft.com/dotnet/2016/09/26/…
  • @lex 感谢您提供指向一篇内容丰富的文章的链接。我想为那些没有听说过这个消息的人指出以下摘录:“为了让 .NET Framework 4.6.1 支持 .NET Standard 2.0,我们不得不从 .NET Standard 中删除所有 API在 .NET Standard 1.5 和 1.6 中引入。”
  • @usr 这个古老的遗留代码是我对 ASP.NET 框架应用程序的第一次尝试。虽然它已经在生产中工作,但它肯定需要重构。我欢迎拉取请求和/或code reviews
  • @usr 此问题的目的是促进完成概念证明存储库,该存储库将旧版 .NET Framework 代码迁移到 .NET Core。该迁移的目的是:(1) 更深入地了解 .NET Core,(2) 发现将遗留代码迁移到 .NET Core 的问题,(3) 测试第三方库到 .NET Core 环境的迁移,以及 (4) 与开源社区分享知识。

标签: c# entity-framework .net-core


【解决方案1】:

您应该能够通过 DbSet 上的 Entity 属性访问实体。您可以直接返回参数或访问 EntityEntry&lt;T&gt;object 以让 ER Core 完全控制要执行的操作:

public virtual T Add(T entity, out CustomMessage customMessage)
{
    var entry = _dbset.Add<T>(entity);
    ...
    return entry.Entity;
}

请注意,目前 EF Core 没有 EF 6 的代理功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 2021-04-07
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多