2016-11-30 2 views
2

Я попытаюсь объяснить эту проблему как можно яснее.Web API & Entity Framework, где указать соединение с базой данных?

Я начинаю с двумя проектами:

Project One: модель данных


Репозиторием класс, который оборачивает DbContext, который имеет один DbSet: RentalListings

Это DbContext ИСПОЛЬЗУЕТ по умолчанию, так что, когда я сохраняю изменения, он сохраняет локальную БД.

Project Two: Console App


Содержит консольное приложение, что, когда запускается, инициализирует экземпляр класса репозитория.

Затем он создает несколько «RentalListings» и сохраняет их в репозитории.


Пока все хорошо. После запуска консольного приложения я проверяю локальный проводник объектов SQL SQL, и мой класс хранилища успешно сэкономлен в этом db.

Теперь я хочу получить доступ к этим вставленным данным через веб-API. Поэтому я добавил:

Project Три: Web API

создать новый класс контроллера и добавить один метод GET действий для извлечения всех списков.

При запуске проекта API, я могу ударить метод действий, который выглядит следующим образом:

[HttpGet] 
public IEnumerable<RentalListing> GetAllListings() { 
      StatsRepository repository = new StatsRepository(new StatsContext()); 
      return repository.GetRentalListings(); 
     } 

через правильный URL. Однако я получаю возвращается следующая ошибка:

Unable to complete operation. The supplied SqlConnection does not specify an initial catalog or AttachDBFileName. 

Теперь от поиска в Интернете, я думаю, проблема в том, что он не знает, как получить доступ к базе данных ??? И что я должен указать строку соединения в файле Web.config в моем проекте веб-API.

Вопросы:

1) Как сделал мой консольное приложение, что не определяет строку подключения, создать базу данных с помощью моего МДФ хранилища класса?

2) Почему не работает то же самое для моего веб-проекта api? не может ли он просто использовать репозиторий для извлечения базы данных, как это делало консольное приложение?

С нетерпением ждем ответов, спасибо заранее!

ответ

1

Вопрос: 1. Как мое консольное приложение, которое не указывает строку подключения, создает базу данных mdf, используя мой класс репозитория?

A: 1. Это по умолчанию. Если вы не указали строку подключения в консольном приложении, она использует пространство имен контекста и имя класса контекста для создания db.

, например.

класс Контекст пространства имен = MyDbContextNameSpace

Имя класса контекста = MyContext

Тогда ваше имя БД будет выглядеть следующим образом: MyDbContextNameSpace.MyContext.

Примечание: Если SQL Express установлен, база данных создается на вашем локальном экземпляре SQL Express (. \ SQLEXPRESS). Если SQL Express не установлен, Code First попытается использовать LocalDb ((localdb) \ v11.0).

Вы можете прочитать об этом здесь: Building an Initial Model & Database

Q: 2. Почему не работает то же самое для моего веб-проекта api? не может ли он просто использовать репозиторий для извлечения базы данных, как это делало консольное приложение?

A: 2. Когда вы разговариваете с EF через Http/s, вы должны указать строку подключения в файле web.config. В противном случае EF не знает, как это сделать. Это по дизайну.

, например.

MyContext.CS

public class MyContext : DbContext 
{ 
    public MyContext() : base(“name=MyContextConn”) 
    { 
    } 

     public DbSet<Blog> Blogs { get; set; } 
} 

web.config

<connectionStrings> 
    <add name=“MyContextConn“ connectionString=“conndetails” 
     providerName=“System.Data.SqlClient“ /> 
</connectionStrings> 
+0

Благодаря кучу для информации. Это помогло мне понять, почему в моем консольном приложении не требуется строка подключения (соглашение означает, что он создал файл MDF с использованием локальной базы данных). Все еще немного облачно, почему проект веб-API, который использует тот же контекст БД, не может сделать то же самое. Но я сейчас просто соглашусь! – AndyNZ

+0

Вы горячо приветствуете :) О вашем вопросе, EF был разработан таким образом, когда вы используете его через HTTP/S (web/web Api). Именно по этой причине он не работает, как консольное приложение в этой ситуации. – Sampath

1
  1. DbContext класс определенно может быть ответственным за «указав строку соединения», как вы выразились, но причина, она наиболее часто встречается в файле конфигурации так, что различные строки соединения могут быть определены для различных конфигураций ,Например, строка подключения Web.Debug.config может указывать на экземпляр SqlExpress, который вы установили в своем окне разработки, а строка подключения Web.Release.config может указывать на экземпляр Sql, содержащийся в Azure.
  2. Задание строки подключения в файле конфигурации необязательно будет исправлять проблему. Строка подключения может указывать имя пользователя и пароль. Если вы поместите их в строку подключения, то это, скорее всего, будет работать. Например, <add name="DefaultConnection" connectionString="Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;" providerName="System.Data.SqlClient" />
  3. Проблема, с которой вы столкнулись, скорее всего связана с тем, что консольное приложение запущено в контексте пользователя Windows, запускающего приложение. Он использует эти учетные данные для подключения к базе данных. Я предполагаю, что ваша консоль, приложение webapi и sql все установлены/запущены на одном компьютере и что ваш пользователь является единственным, который вы используете для входа в sql (опять же, если вы используете SSMS). Веб-приложение, скорее всего, выполняется через IIS или IISExpress, который по умолчанию запускается в другом контексте (я считаю, IUSR для IIS). Если вы хотите, чтобы ваша строка подключения использовала встроенную защиту (чтобы сохранить свое имя пользователя и пароль из ваших конфигураций, что обычно считается хорошей практикой), например: <add name="DefaultConnection" connectionString="Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=True" providerName="System.Data.SqlClient" />, тогда вы хотите настроить контекст, который приложение запускается под обновлением пользователя, в котором работает приложение. Вы сделаете это с помощью updating the app pool identity, а затем убедитесь, что веб-приложение using that app pool.

Надеюсь, это поможет.

Смежные вопросы