2

我正在尝试设置一个带有可移植区域(在单独的项目中)和通用存储库的 asp.net mvc。

我使用 IContext 接口为实现该接口的每个上下文生成数据库:

public class Context : DbContext
    {
        public List<IContext> Contexts {get;set;}

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            foreach (IContext context in Contexts)
                context.Setup(modelBuilder);
        }
    }

和 IContext 的实现:

public class TaskListContext : Context, IContext
    {
        public DbSet<Task> Tasks { get; set; }

        void IContext.Setup(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Task>().ToTable("Tasks");
            modelBuilder.Entity<Task>().HasKey(task => task.Id);            
        }
    }

当我运行此代码时:

Context context = new Context();
            context.Contexts = new List<IContext>();
            context.Contexts.Add(new ModuleContext());

            String assemblyPath = ControllerContext.HttpContext.Server.MapPath(String.Format("~/bin/{0}", "TaskList.dll")); //it is in a seperate project.

            Assembly assembly = Assembly.LoadFrom(assemblyPath);

            var contexts = from t in assembly.GetExportedTypes()
                              where typeof(IContext).IsAssignableFrom(t)
                              select t;
            foreach (Type t in contexts)
            {
                IContext cont = (IContext)Activator.CreateInstance(t);
                context.Contexts.Add(cont);             
            }

            context.Database.CreateIfNotExists();

数据库和表按预期创建。

但是当我想用存储库模式查询数据库时,我得到一个错误。

查询:

TaskListRepository Rep = new TaskListRepository();
            var task = Rep.FindBy(t => t.Id==2);

存储库:

public class TaskListRepository : GenericRepository<TaskListContext, Task>, ITaskListRepository
    {
    }

抽象存储库:

public abstract class GenericRepository<C, T> :
    IGenericRepository<T>
        where T : class
        where C : DbContext, new()
    {

        private C _entities = new C();

        public C ConcreteContext
        {

            get { return _entities; }
            set { _entities = value; }
        }

        public virtual IQueryable<T> GetAll()
        {
            IQueryable<T> query = _entities.Set<T>();
            return query;
        }

        public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {

            IQueryable<T> query = _entities.Set<T>().Where(predicate);
            return query;
        }

        public virtual void Add(T entity)
        {
            _entities.Set<T>().Add(entity);
        }

        public virtual void Delete(T entity)
        {
            _entities.Set<T>().Remove(entity);
        }

        public virtual void Edit(T entity)
        {
            _entities.Entry(entity).State = System.Data.EntityState.Modified;
        }

        public virtual void Save()
        {
            _entities.SaveChanges();
        }
    }

然后我得到这个错误:

建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。(提供者:SQL 网络接口,错误:26 - 错误定位服务器/指定的实例)

堆栈跟踪:

[SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)]
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +6351920
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412
   System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity) +6366506
   System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, SqlConnection owningObject) +180
   System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout) +6366917
   System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance) +6366793
   System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance) +352
   System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) +831
   System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options) +49
   System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject) +6368598
   System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject) +78
   System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +2194
   System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +89
   System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6372110
   System.Data.SqlClient.SqlConnection.Open() +300
   System.Data.SqlClient.SqlProviderServices.UsingConnection(SqlConnection sqlConnection, Action`1 act) +132
   System.Data.SqlClient.SqlProviderServices.UsingMasterConnection(SqlConnection sqlConnection, Action`1 act) +3981391
   System.Data.SqlClient.SqlProviderServices.GetDbProviderManifestToken(DbConnection connection) +10513049
   System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +44

[ProviderIncompatibleException: The provider did not return a ProviderManifestToken string.]
   System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +11121429
   System.Data.Entity.ModelConfiguration.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection) +94

[ProviderIncompatibleException: An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct.]
   System.Data.Entity.ModelConfiguration.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection) +357
   System.Data.Entity.ModelConfiguration.Utilities.DbConnectionExtensions.GetProviderInfo(DbConnection connection, DbProviderManifest& providerManifest) +108
   System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) +118
   System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) +237
   System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) +279
   System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +888
   System.Data.Entity.Internal.InternalContext.Initialize() +50
   System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +45
   System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +151
   System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +50
   System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() +140
   System.Linq.Queryable.Where(IQueryable`1 source, Expression`1 predicate) +135
   MonackFr.Repository.GenericRepository`2.FindBy(Expression`1 predicate) in D:\code\MonackFr\MonackFr\MonackFr.Library\Repository\GenericRepository.cs:34
   MonackFr.Mvc.Areas.TaskList.Controllers.TaskController.Index() in D:\code\MonackFr\MonackFr\MonackFr.Mvc\MonackFr.Mvc\Areas\TaskList\Controllers\TaskController.cs:18
   lambda_method(Closure , ControllerBase , Object[] ) +113
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +261
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
   System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +34
   System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +129
   System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +954935
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +15
   System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +33
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +955452
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +28
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +67
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +53
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__4(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375

连接字符串:

<connectionStrings>
      <add name="Context" providerName="System.Data.SqlClient" connectionString="Data Source=localhost;Initial Catalog=monackfr;User Id=sa;Password=*******" />       
  </connectionStrings>

我真的再也看不到了?有谁知道出了什么问题?连接字符串应该是正确的:它正在创建数据库和表。

问候,

威廉

4

1 回答 1

1

EF 有很多有用的约定。其中之一是 EF 尝试自动找出连接字符串。

如果您没有另外指定并且配置文件中没有连接字符串,EF 将根据DbContext类型名称创建一个具有数据库名称的连接字符串。

因此,当您使用它时,可以在您的配置Context中找到您的连接字符串。name="Context"但是当你使用TaskListContext它时找不到连接字符串,name='TaskListContext'所以它会为你生成一个连接字符串,这将导致你得到的异常。

name='TaskListContext'为避免这种情况,您可以在 app/web.config中添加一个新的连接字符串

或者,您可以使用DbContext 构造函数重载之一来明确指定连接。根据您当前的设计,它应该如下所示:

public class Context : DbContext
{
    public Context()
    {
    }

    public Context(string nameOrConnectionString) : base(nameOrConnectionString)
    {
    }

    //.. rest of Context 
}

public class TaskListContext : Context, IContext
{
    public TaskListContext() : base("Context")
    {
    }

     //.. rest of TaskListContext 
}

IContext通过在所有派生类型中进行此修改, EF 将为"Context"每个 DbContext 使用从配置文件中命名的相同连接字符串。

于 2012-07-17T08:07:49.167 回答