今天在改写架构的时候,遇到这么个错误。当时单从字面意思,看上去错误是由join的两个不同的表来源不一致引起的。

image

其中的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,我们的错误消失了,看来最后的推测是对的。

谨以此文,权当抛砖引玉。

posted on 2014-09-03 15:05  程序诗人  阅读(3448)  评论(0编辑  收藏  举报