How to set the right AttachDbFilename relative path in ASP.NET Core?

asp.net-core c# entity-framework

Question

Working in Visual Studio 2015 on a web project that uses LocalDb v11.0, EF Core (formerly EF 7), ASP.NET Core (formerly ASP.NET 5), and.NET Core CLR RC1.

I manually constructed a database and put MDF/LDF files in a project subdirectory using SQL instructions, similar to:

MySolution\src\MyProject\MyLocalData\
  - MyLocalDb.mdf
  - MyLocalDb_log.ldf

The worth of is this."ConnectionString" lockset inappsettings.json (or at least one I tried out of several)

"Data Source=(LocalDb)\\v11.0;AttachDbFilename=.\\MyLocalData\\MyLocalDb.mdf;Integrated Security=True"

I've correctly created the initial migration, but I'm now stopped atdnx ef database update command, which results in the following error:

Error Number:15350,State:1,Class:14 An attempt to attach an auto-named database for file .\MyLocalData\MyLocalDb.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.

After looking for files in my user home directory and databases in the LocalDb instance in SQL Server Management Studio, I'm confident there isn't another database with that name. In actuality, if I change to an absolute filepath inAttachDbFilename The migration continues (and discovers other issues pertaining to column properties set through the EF Fluent interface, but that's another story).

Therefore, it seems to me that all of this will depend on choosing the proper relative path to employ inAttachDbFilename . I looked through the comparable issues on SO, but I was unable to locate an answer. Additionally, I attempted to alter the relative path by assuming that the current folderwwwroot , or theartifacts a folder, but to no avail.

Does anyone know how to set this up properly? TA

1
5
5/5/2016 7:22:32 PM

Accepted Answer

It took a lot of work, but I now have this working. The environment variable "ContentRootPath," which in your case returns the path for MySolutionsrc, is crucial in this. MyProject

The "Database First" instruction that comes after https://docs.efproject.net/en/latest/platforms/aspnetcore/existing-db.html is my test app.

with modifications, such as this one, to fit my circumstances of teaching web application programming and the necessity for independent apps that I and students can run on each other's computers for discussion, grading, etc.

the appsettings.json file

    {
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;AttachDBFilename=%CONTENTROOTPATH%\\App_Data\\blogging.mdf;Trusted_Connection=true;MultipleActiveResultSets=true"
  }

the distinguishing feature being:

AttachDBFilename=%CONTENTROOTPATH%\\App_Data\\blogging.mdf

Okay, I'm using the conventional name "App Data," but the ContentRootPath is a more safe location than "wwwroot."

Afterward, in Startup.cs

public class Startup
{
    //20160718 JPC enable portable dev database
    private string _contentRootPath = "";

    public Startup(IHostingEnvironment env)
    {
        //20160718 JPC enable portable dev database
        _contentRootPath = env.ContentRootPath;
    ...
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //20160718 JPC enable portable dev database
        string conn = Configuration.GetConnectionString("DefaultConnection");
        if(conn.Contains("%CONTENTROOTPATH%"))
        {
            conn = conn.Replace("%CONTENTROOTPATH%", _contentRootPath);
        }
        ...
     }

In the example above, "..." denotes the default code produced by Visual Studio 2015.

Please take note that custom directories and files, such as my "App Data" folder, must be manually copied and pasted into the published version of an app when we "Publish" one like this. OR we can amend the "project.json" file to include the unique folder name, in this example "App Data."

It's also helpful to know that we can add a constructor function with the parameter env to any class, including controller classes, and the hosting environment will provide us with useful data like the ContentRootPath. useful for offering file upload for our users, for example, custom file storage.

public class HomeController : Controller
{
    //20160719 JPC access hosting environment via controller constructors
    private IHostingEnvironment _env;

    public HomeController(IHostingEnvironment env)
    {
        _env = env;
    }

    public IActionResult Index()
    {
        string contentRootPath = _env.ContentRootPath;
        return View();
    }

Okay, this is only to illustrate the idea. To illustrate, I added a breakpoint on "return View()" and moved the mouse pointer over contentRootPath.

One of the more difficult topics for studying and teaching that I have encountered is ASP.NET Core MVC6. For all of us, good luck with it. I came across a good development: Getting our custom data and the identity AspNetUser columns to live together peacefully in one database in MVC5 was not without its challenges. It appears that the MVC6 solution is a cleaner and more organized one.

11
7/21/2016 12:02:09 AM

Popular Answer

ZZZ_tmp


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow