asp.net MVC произошла ошибка, связанная с сетью или конкретным экземпляром


Я пытаюсь установить 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:codeMonackFrMonackFrMonackFr.LibraryRepositoryGenericRepository.cs:34
   MonackFr.Mvc.Areas.TaskList.Controllers.TaskController.Index() in D:codeMonackFrMonackFrMonackFr.MvcMonackFr.MvcAreasTaskListControllersTaskController.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>

Я действительно больше не вижу его? Кто-нибудь знает, что происходит? Строка connectionstring должна быть правильной: она создает базу данных и таблицы.

С уважением,

Виллем

1 2

1 ответ:

У EF есть много полезных соглашений. Один из них заключается в том, что EF пытается автоматически узнать строку подключения.

Если вы не указали иное и в вашем конфигурационном файле нет строки подключения, EF создаст ее с именем БД, основанным на имени типа DbContext.

Поэтому при использовании Context он может найти строку соединения с name="Context" в вашей конфигурации. Но когда вы используете TaskListContext, он не может найти строку соединения с name='TaskListContext', поэтому он будет генерировать строку соединения для вас, которые приведут к исключению, что вы получите.

Чтобы избежать этого, вы можете добавить новую строку соединения с name='TaskListContext' в вашем приложении/интернете.config

Или вы можете использовать одну из перегрузок DbContext contructor, чтобы указать соединение неявно. С вашим текущим дизайном он должен выглядеть следующим образом:

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.