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

sup*_*jos 5 c# entity-framework asp.net-core

在基于ASP.NET Core(以前的ASP.NET 5),.NET Core CLR RC1,EF Core(以前的EF 7),启用EF迁移,LocalDb v11.0的Web项目中使用VS2015.

我手动(通过SQL命令)创建了一个数据库并将MDF/LDF文件放在一个项目子目录中,情况类似于:

MySolution\src\MyProject\MyLocalData\
  - MyLocalDb.mdf
  - MyLocalDb_log.ldf
Run Code Online (Sandbox Code Playgroud)

这是"ConnectionString"密钥集的值appsettings.json(或者至少是我尝试的众多密钥之一):

"Data Source=(LocalDb)\\v11.0;AttachDbFilename=.\\MyLocalData\\MyLocalDb.mdf;Integrated Security=True"
Run Code Online (Sandbox Code Playgroud)

初始迁移已经正确创建,现在我遇到了dnx ef database update命令(参见官方教程),它给出了这个错误:

错误号:15350,状态:1,类:14尝试为文件附加自动命名的数据库.\ MyLocalData\MyLocalDb.mdf失败.存在具有相同名称的数据库,或者无法打开指定的文件,或者它位于UNC共享上.

我很确定没有其他具有该名称的数据库,在我的用户主目录中检查了文件,在Sql Server Management Studio中检查了LocalDb实例中的数据库.事实上,如果我切换到绝对文件路径AttachDbFilename,迁移会进一步移动(并找到与通过EF流畅界面设置的列属性相关的其他错误,但这是另一个故事).

因此,我认为这是找到正确的相对路径使用的问题AttachDbFilename.我在这里搜索了SO的相关主题,但找不到任何答案.我也尝试改变想象当前文件夹wwwrootartifacts文件夹的相对路径,但没有运气.

有没有人知道如何正确设置它?TA

iaf*_*ilm 11

我现在有这个工作,这是艰苦的工作.关键是环境信息"ContentRootPath",在您的示例中将返回MySolution\src\MyProject的路径

我的测试应用程序是https://docs.efproject.net/en/latest/platforms/aspnetcore/existing-db.html之后的"数据库优先"教程

包括这个在内的变化适合我的网络应用程序编程教学和需要自包含的应用程序,我和学生可以在彼此的机器上运行讨论,标记等.

在appsettings.json中

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

独特的部分是:

AttachDBFilename=%CONTENTROOTPATH%\\App_Data\\blogging.mdf
Run Code Online (Sandbox Code Playgroud)

好的我使用的是传统名称"App_Data",但在ContentRootPath下更安全,而不是在"wwwroot"下.

然后在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);
        }
        ...
     }
Run Code Online (Sandbox Code Playgroud)

在上面的"..."代表Visual Studio 2015生成的标准代码.

请注意,当我们"发布"这样的应用程序时,我们需要手动将自定义文件夹和文件(例如我的"App_Data"文件夹)复制并粘贴到已发布的版本中.或者我们可以将自定义文件夹名称(在本例中为"App_Data")添加到文件"project.json".

知道对于任何包含控制器类的类,我们都可以添加带参数env的构造函数方法,托管环境将为我们提供包括ContentRootPath在内的有用信息.用于自定义文件存储,例如为我们的用户提供文件上载.

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();
    }
Run Code Online (Sandbox Code Playgroud)

好吧,这只是为了演示原理,就像我在"返回View()"上添加一个断点然后将鼠标悬停在contentRootPath上来制作点.

ASP.NET Core MVC6看起来像是我遇到的更大的学习和教学挑战之一.祝我们所有人好运.我找到了一个很好的进步:在MVC5中我们有一些戏剧性的获取我们的自定义数据和身份AspNetUser表在一个数据库中很好地共存.看起来它在MVC6中作为一个更整洁更整洁的命题.