【问题标题】:Repository Pattern with Entity Framework and MVC4 Building Dynamic Connection String使用实体框架和 MVC4 构建动态连接字符串的存储库模式
【发布时间】:2014-01-17 08:36:23
【问题描述】:

我在使用 EF6 为 MVC4 实施存储库模式 [UoW] 时遇到问题。

错误:“XX.DataAccess.Context”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“XX.DataAccess.WriteRepository”中的参数“TContext”

//Data Access layer Class for Saving/Deleting/Retriving etc. Inherits WriteRepository
public class Common : WriteRepository<Context>, ICommon
{
    //Method
}

//Repository Pattern
public abstract class WriteRepository<TContext> : IWriteRepository where TContext : DbContext, new()
{
    private readonly TContext _context;

    protected TContext Context { get { return _context; } }

    protected WriteRepository()
    {
        _context = new TContext();
    }

//Save Method

//Delete Method

//Retrive Method

//Find Method
}

//数据库上下文类 //这里我需要建立以客户端ID为参数的动态连接字符串。如果我在参数中使用它,它会给我上面提到的数据访问方法实现的错误。

public partial class Context : DbContext
{
    static Context ()
    {
        Database.SetInitializer<Context>(null);
    }

    public Context (int ClientID = 0)
        : base(ConnectionString(ClientID))
    {
        var objContext = (this as IObjectContextAdapter).ObjectContext;
        objContext.CommandTimeout = 180;
    }

//DBSet's

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    //Mapping
}

private static string ConnectionString(int ClientID = 0)
    {
    //return connection string
}
}

让我知道我需要进行哪些更改才能使其正常工作。

【问题讨论】:

    标签: entity-framework asp.net-mvc-4 .net-4.5 repository-pattern dbcontext


    【解决方案1】:

    问题在于WriteRepository 上的new() 约束。无法满足约束,因为Context 没有零参数构造函数,因为您需要在创建ClientID 时传入它。因此,删除new() 约束,改为修改WriteRepository 构造函数以采用TContext 类型的参数:

    //Repository Pattern
    public abstract class WriteRepository<TContext> : IWriteRepository where TContext : DbContext
    {
        private readonly TContext _context;
    
        protected TContext Context { get { return _context; } }
    
        protected WriteRepository(TContext context)
        {
            _context = context;
        }
    
        //Save Method
    
        //Delete Method
    
        //Retrive Method
    
        //Find Method
    
    }
    

    然后,在派生类中,创建Context 并将其作为参数传递给基构造函数。

    //Data Access layer Class for Saving/Deleting/Retriving etc. Inherits WriteRepository
    public class Common : WriteRepository<Context>, ICommon
    {
        public Common(int clientID)
            :base(new Context(clientID))
        {
    
        }
    }
    

    当然,已经从WriteRepository 派生的任何其他类也需要进行修改。我希望这会有所帮助!

    【讨论】:

    • 嗨@luksan。感谢您的帮助。实际上,如果我们指定此方法,则每次 ClientID 都会为 0。目的是从 UI -> 业务 -> 数据访问发送客户端 ID。这是一个多租户数据库,我想知道选择了哪个客户端。基于这个客户端,我将构建上面代码中提到的动态连接字符串。我将从我们的集中式数据库中获得它[尚未在代码中实现它,但它更容易]。使用您提供的方法,它将始终为零。还有什么可以做的?任何的想法?公共上下文():this(0){}
    • 对不起,我部分误解了你的问题。我已经更新了我的答案来解决这个问题。
    • 嘿@Luksan .. 非常感谢.. 解决了:) 你提到的代码只有一个变化。 public WriteRepository(int clientID):base(new Context(clientID)) 要更改为.. public Common (int clientID):base(new Context(clientID)) 它工作得很好.. :) 谢谢兄弟...
    • 很高兴它成功了......请不要忘记投票/接受我的答案,以便我得到一些分数。 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2014-01-04
    相关资源
    最近更新 更多