今天在改写架构的时候,遇到这么个错误。当时单从字面意思,看上去错误是由join的两个不同的表来源不一致引起的。
其中的videoResult和deerpenList均来自与同一个edmx文件,所以两个表的来源不一致导致了错误的发生,这个猜想是不正确的。
正在左右为难之际,在stackoverflow上面发现了一个主题,正好解决了我的难题。这个问题的回答是这样的:
This can happen if your Context property returns a new instance every time
它的字面意思是:如果你的Context每次访问都返回一个新的实例的话,就会造成这个错误。
回想起我之前的构造:
public interface IContext<T>:IDisposable where T: class { DbContext DbContext{ get ;} IDbSet DbSet{ get ;} } public class Context<T>:IContext<T> where T: class { public Context() { DbContext = new DbContext(ConfigurationManager.ConnectionStrings[ "GDeerGardenEntities" ].ConnectionString); DbSet = DbContext.Set<T>(); } public void Dispose() { DbContext.Dispose(); } public DbContext DbContext { get ; private set ; } public IDbSet<T> DbSet { get ; private set ; } } |
由于每次调用,都会新建一个DbContext,所以导致错误的发生。找到原因所在,就好了,我们只需要利用autofac这个ioc容器就行,使用的时候,从容器拿就行了。
所以打开安装器,输入
install-package autofac.mvc3 -project GDeerParkWeb |
然后安装完毕,注入一下:
builder.RegisterGeneric( typeof (Context<>)).As( typeof (IContext<>)).SingleInstance(); |
本以为这样就没问题了。但是在使用的时候,依然会出现上述的错误。
到底原因在哪里呢? 这次排查的线索都断掉了。
想了好久,最后发现可能是泛型的Context存在问题,为什么呢?
因为在取实例化的时候,按照目前的设计,实例上下文应该是这样取得:
Context<bas_video>, Context<bas_deerpen>.
这样,带来的问题就显而易见了: 这两个上下文会产生两个不同的实例!!!!!!!
为什么会产生两个不同的实例呢? 因为泛型T只是一个占位符,当实例化出来的时候,泛型的上下文当然会拿不同的实例去hold住,这样就会造成在进行join操作的时候,出现开头的错误。
如果真是这样,那么我们把去掉,不就可以了吗?
这次我们的重构如下:
public interface IContext { IDbSet<T> DbSet<T>() where T : class ; DbContext DbContext { get ; } } public class Context:DbContext,IContext { public Context() : base ( "GDeerGardenEntities" ) {} public IDbSet<T> DbSet<T>() where T : class { return base .Set<T>(); } public new DbContext DbContext { get ; private set ; } } |
我们的容器注入如下:
builder.RegisterType<Context>().As<IContext>().SingleInstance(); |
最后上阵使用,wow,我们的错误消失了,看来最后的推测是对的。
谨以此文,权当抛砖引玉。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!