简体   繁体   English

如何在ASP.NET Core中设置正确的AttachDbFilename相对路径?

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

Working in VS2015 on a web project based on ASP.NET Core (former ASP.NET 5), .NET Core CLR RC1, EF Core (former EF 7), EF Migrations enabled, LocalDb v11.0. 在基于ASP.NET Core(以前的ASP.NET 5),.NET Core CLR RC1,EF Core(以前的EF 7),启用EF迁移,LocalDb v11.0的Web项目中使用VS2015。

I manually (through SQL commands) created a database and placed MDF/LDF files in a project subdirectory, a situation similar to: 我手动(通过SQL命令)创建了一个数据库并将MDF / LDF文件放在一个项目子目录中,情况类似于:

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

This is the value of "ConnectionString" key set in appsettings.json (or at least, one of the many I tried): 这是appsettings.json设置的"ConnectionString"键的值(或者至少是我尝试过的许多键之一):

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

The initial migration has been created correctly, now I'm stuck at dnx ef database update command (see official tutorial ), which gives this error: 初始迁移已正确创建,现在我停留在dnx ef database update命令(请参阅官方教程 ),这会出现此错误:

Error Number:15350,State:1,Class:14 An attempt to attach an auto-named database for file .\\MyLocalData\\MyLocalDb.mdf failed. 错误号:15350,状态:1,类:14尝试为文件附加自动命名的数据库。\\ MyLocalData \\ MyLocalDb.mdf失败。 A database with the same name exists, or specified file cannot be opened, or it is located on UNC share. 存在具有相同名称的数据库,或者无法打开指定的文件,或者它位于UNC共享上。

I'm pretty sure there's no other DB with that name, having checked both in my user home directory for files, and in Sql Server Management Studio for databases in LocalDb instance. 我很确定没有其他具有该名称的数据库,在我的用户主目录中检查了文件,在Sql Server Management Studio中检查了LocalDb实例中的数据库。 As a matter of fact, if I switch to an absolute filepath in AttachDbFilename , the migration moves further (and finds other errors related to column properties set through EF fluent interface, but that's another story). 事实上,如果我切换到AttachDbFilename的绝对文件路径,迁移会进一步移动(并找到与通过EF流畅界面设置的列属性相关的其他错误,但这是另一个故事)。

So it looks to me this is all a matter of finding the right relative path to use in AttachDbFilename . 因此,我认为这是在AttachDbFilename中找到正确的相对路径。 I searched here on SO for related topics, but could not find any answer. 我在这里搜索了SO的相关主题,但找不到任何答案。 I also tried changing the relative path imagining that the current folder was wwwroot , or the artifacts folder, but with no luck. 我也尝试改变想象当前文件夹是wwwrootartifacts文件夹的相对路径,但没有运气。

Does any one know how to correctly set this? 有没有人知道如何正确设置它? TA TA

I do now have this working and it was hard work. 我现在有这个工作,这是艰苦的工作。 The key to this is the environment information "ContentRootPath" which in your example will return the path for MySolution\\src\\MyProject 关键是环境信息“ContentRootPath”,在您的示例中将返回MySolution \\ src \\ MyProject的路径

My test app is the "Database First" tutorial following https://docs.efproject.net/en/latest/platforms/aspnetcore/existing-db.html 我的测试应用程序是https://docs.efproject.net/en/latest/platforms/aspnetcore/existing-db.html之后的“数据库优先”教程

with changes including this one to suit my situation of teaching web app programming and needing self contained apps that I and students can run on each other's machines for discussion, marking etc. 包括这个在内的变化适合我的网络应用程序编程教学和需要自包含的应用程序,我和学生可以在彼此的机器上运行讨论,标记等。

In appsettings.json 在appsettings.json中

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

With the distinctive part being: 独特的部分是:

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

OK I am using the traditional name "App_Data" but it is more securely under the ContentRootPath rather than under "wwwroot". 好的我使用的是传统名称“App_Data”,但在ContentRootPath下更安全,而不是在“wwwroot”下。

Then in Startup.cs 然后在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 above "..." represents the standard code generated by Visual Studio 2015. 在上面的“...”代表Visual Studio 2015生成的标准代码。

NOTE that when we "Publish" an app like this, we need to manually copy and paste custom folders and files, eg my "App_Data" folder, into the published version. 请注意,当我们“发布”这样的应用程序时,我们需要手动将自定义文件夹和文件(例如我的“App_Data”文件夹)复制并粘贴到已发布的版本中。 OR we can add the custom folder name, in this case "App_Data", to the file "project.json". 或者我们可以将自定义文件夹名称(在本例中为“App_Data”)添加到文件“project.json”。

It is also good to know that for any class including controller classes, we can add a constructor method with parameter env and the hosting environment will feed us useful information including ContentRootPath. 知道对于任何包含控制器类的类,我们都可以添加带参数env的构造函数方法,托管环境将为我们提供包括ContentRootPath在内的有用信息。 Useful for custom file storage eg providing file upload for our users. 用于自定义文件存储,例如为我们的用户提供文件上载。

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();
    }

OK this is only to demo the principle as in I add a breakpoint on "return View()" then hover the mouse over contentRootPath to make the point. 好的,这只是为了演示原理,就像我在“返回View()”上添加一个断点然后将鼠标悬停在contentRootPath上来制作点。

ASP.NET Core MVC6 looks like one of the bigger learning and teaching challenges I have run into. ASP.NET Core MVC6看起来像是我遇到的更大的学习和教学挑战之一。 Good luck with it for all of us. 祝我们所有人好运。 I have found one nice advance: In MVC5 we had some drama getting our custom data and the identity AspNetUser tables to live together nicely in one database. 我找到了一个很好的进步:在MVC5中我们有一些戏剧性的获取我们的自定义数据和身份AspNetUser表在一个数据库中很好地共存。 Looks like it is working out as a more neat and tidy proposition in MVC6. 看起来它在MVC6中作为一个更整洁更整洁的命题。

I found an easier way around 我找到了一个更简单的方法

  1. run your app and create the DB in the default location 运行您的应用程序并在默认位置创建数据库

  2. Open Microsoft Sql Server Management Studio (or you prefer IDE) and create a new connection to point to (localdb)\\mssqllocaldb 打开Microsoft Sql Server Management Studio(或者您更喜欢IDE)并创建一个新连接以指向(localdb)\\ mssqllocaldb

  3. Script Database as CREATE 脚本数据库为CREATE

  4. Change the path in the FILENAME 更改FILENAME中的路径

  5. Remove the DB you created on step 1 (choose close existing connections) 删除在步骤1中创建的数据库(选择关闭现有连接)

  6. Run the script 运行脚本

Your application should work without changing anything in the config 您的应用程序应该在不更改配置中的任何内容的情

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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