简体   繁体   中英

Web API & Entity Framework, Where to specify Database connection?

I am going to try and explain this issue as clear as I can.

I start with two projects:

Project One: Data model


A repository class that wraps a DbContext that has a single DbSet: RentalListings

This DbContext uses the default settings, so that when I save changes it saves to local DB.

Project Two: Console App


Contains a console application that when runs, instantiates an instance of the repository class.

Then it creates multiple "RentalListings" and saves them to the repository.


So far so good. After running the console app I check the local DB SQL object explorer, and my repository class has successfuly saved to this db.

Now, I want a way to access this inserted data via a Web API. So I add:

Project Three: Web API

I create a new controller class and add a single GET action method to fetch all listings.

When I run the API project, I can hit the action method, which looks like:

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

via the correct URL. However I am getting the following error returned:

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

Now, from searching the web I think the issue is that it doesn't know how to access the database??? And that I should specify a connection string in the Web.config file in my Web API project.

Questions:

1) How did my console app, that doesn't specify a connection string, create a mdf database using my repository class?

2) Why doesn't the same work for my web api project? can't it just use the repository to fetch the database, just like the console app did?

Look forward to hearing the replies, thanks in advance!

Q :1. How did my console app, that doesn't specify a connection string, create a mdf database using my repository class ?

A :1. It is by default.If you didn't specify the connection string on console app then it uses your context class namespace plus name of the context class to create a db.

eg

Context class namespace = MyDbContextNameSpace

Name of the context class = MyContext

Then your DB name will be like this : MyDbContextNameSpace.MyContext .

Note : If SQL Express is installed then the database is created on your local SQL Express instance (.\\SQLEXPRESS). If SQL Express is not installed then Code First will try and use LocalDb ((localdb)\\v11.0).

You can read more about it here : Building an Initial Model & Database

Q :2. Why doesn't the same work for my web api project? can't it just use the repository to fetch the database, just like the console app did?

A :2. When you talk to EF through Http/s ,you have to provide the connection string on web.config file. Otherwise EF doesn't know how to do that.That is by design.

eg

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>
  1. The DbContext class can definitely be responsible for 'specifying a connection string', as you put it, but the reason it is most commonly found in a config file is so that different connection strings can be specified for different configurations. For example, your Web.Debug.config connection string might point to an instance of SqlExpress that you have installed on your development box and the Web.Release.config connection string might point to a Sql instance contained in Azure.
  2. Specifying a connection string in your config file isn't necessarily going to fix the issue. The connection string can specify a username and a password. If you put those in to the connection string then it will most likely work. For example <add name="DefaultConnection" connectionString="Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;" providerName="System.Data.SqlClient" /> <add name="DefaultConnection" connectionString="Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;" providerName="System.Data.SqlClient" />
  3. The issue you are experiencing is most likely due to the fact that the console application is running under the context of the Windows user launching the application. It is using those credentials to connect to the database. I'm assuming that your console, webapi app and sql are all installed/running on the same machine and that your user is the only one that you use to log in to sql(again assuming you are using SSMS). The web application though is most likely being run through IIS or IISExpress which is run under a different context by default(I believe IUSR for IIS). If you would like to have your connection string use integrated security(to keep your username and password out of your configs -- which is generally considered a good practice) like this: <add name="DefaultConnection" connectionString="Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=True" providerName="System.Data.SqlClient" /> then you would want to setup the context that the application is being run under by updating the user the apppool is running under. You would do this by updating the app pool identity and then making sure that the web application is using that app pool .

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM