Где находится | DataDirectory | определены?

Честно говоря, мне нравится первый способ OP начать его с помощью значения NULL, а затем проверить его с помощью is.null (в первую очередь потому, что это очень просто и легко понять). Возможно, это зависит от того, как люди привыкли к кодированию, но Хэдли, похоже, поддерживает и путь is.null:

Из книги Хэдли «Advanced-R» Глава 6, Функции, стр.84 (для здесь ):

Вы можете определить, был ли аргумент предоставлен или нет с функцией missing ().

i <- function(a, b) {
  c(missing(a), missing(b))
}
i()
#> [1] TRUE TRUE
i(a = 1)
#> [1] FALSE  TRUE
i(b = 2)
#> [1]  TRUE FALSE
i(1, 2)
#> [1] FALSE FALSE

Иногда вы хотите добавить нетривиальное значение по умолчанию, которое может занять несколько строк кода. Вместо того, чтобы вставлять этот код в определение функции, вы можете использовать missing () для условного вычисления, если это необходимо. Однако это затрудняет понимание того, какие аргументы необходимы и которые являются необязательными, без тщательного изучения документации. Вместо этого я обычно устанавливаю значение по умолчанию NULL и использую is.null (), чтобы проверить, был ли предоставлен аргумент.

41
задан Community 23 May 2017 в 12:25
поделиться

3 ответа

|DataDirectory| не является файлом как таковым. Цитата из этой довольно старой статьи MSDN (подробнее читайте в полной статье):

По умолчанию переменная | DataDirectory | будет расширена как следуйте:

  • Для приложений, размещенных в каталоге на пользовательском компьютере, это будет папка приложения (.exe).
  • Для приложений, работающих под ClickOnce, это будет специальная папка данных, созданная ClickOnce.
  • Для веб-приложений это будет папка App_Data.

. для | DataDirectory | просто происходит из свойства в домене приложения. Можно изменить это значение и переопределить поведение по умолчанию, выполнив следующее:

AppDomain.CurrentDomain.SetData("DataDirectory", newpath)

Еще одна цитата относительно несоответствий вашей схемы:

Одна из вещей знать при работе с локальными файлами базы данных, что они обрабатываются как любые другие файлы содержимого. Для настольных проектов это означает, что по умолчанию файл базы данных будет копироваться в выходную папку (он же bin) при каждой сборке проекта. После F5 вот как это будет выглядеть на диске

 MyProject\Data.mdf

 MyProject\MyApp.vb

 MyProject\Bin\Debug\Data.mdf

 MyProject\Bin\Debug\MyApp.exe

Во время разработки MyProject \ Data.mdf используется инструментами данных. Во время выполнения приложение будет использовать базу данных в выходной папке. В результате копирования у многих создалось впечатление, что приложение не сохранило данные в файл базы данных. На самом деле это просто потому, что задействованы две копии файла данных. То же самое касается просмотра схемы / данных через проводник баз данных. Инструменты используют копию в проекте, а не ту, которая находится в папке bin.

62
ответ дан MicSim 23 May 2017 в 12:25
поделиться

На форуме MSDN есть похожий, но упрощенный вопрос об этом, который говорит:

По умолчанию | DataDirectory | указывает на папку вашего приложения (как вы выяснили в исходном вопросе: на App_Data).

Так как это просто путь замещения к вашей базе данных, вы можете сами определить путь с помощью AppDomain.SetData .

2
ответ дан András Ottó 23 May 2017 в 12:25
поделиться

Каталог данных | Алгоритм находится в сборке System.Data.dll, во внутреннем классе System.Data.Common.DbConnectionOptions. Вот как показано ILSpy (обратите внимание на источник, который теперь доступен в репозитории справочных источников: https://github.com/Microsoft/referencesource/blob/e458f8df6ded689323d4bd1a2a725ad32668aaec/System.Data.Entity/ System / Data / EntityClient / DbConnectionOptions.cs ):

internal static string ExpandDataDirectory(string keyword,
                                           string value,
                                           ref string datadir)
{
    string text = null;
    if (value != null && 
        value.StartsWith("|datadirectory|", StringComparison.OrdinalIgnoreCase))
    {
        string text2 = datadir;
        if (text2 == null)
        {
            // 1st step!
            object data = AppDomain.CurrentDomain.GetData("DataDirectory");
            text2 = (data as string);
            if (data != null && text2 == null)
                throw ADP.InvalidDataDirectory();

            if (ADP.IsEmpty(text2))
            {
                // 2nd step!
                text2 = AppDomain.CurrentDomain.BaseDirectory;
            }
            if (text2 == null)
            {
                text2 = "";
            }
            datadir = text2;
        }

        // 3rd step, checks and normalize
        int length = "|datadirectory|".Length;
        bool flag = 0 < text2.Length && text2[text2.Length - 1] == '\\';
        bool flag2 = length < value.Length && value[length] == '\\';
        if (!flag && !flag2)
        {
            text = text2 + '\\' + value.Substring(length);
        }
        else
        {
            if (flag && flag2)
            {
                text = text2 + value.Substring(length + 1);
            }
            else
            {
                text = text2 + value.Substring(length);
            }
        }
        if (!ADP.GetFullPath(text).StartsWith(text2, StringComparison.Ordinal))
            throw ADP.InvalidConnectionOptionValue(keyword);
    }
    return text;
}

Таким образом, сначала он просматривает текущие данные AppDomain (по умолчанию нет данных «DataDirectory», определенных, как мне кажется), а затем получает в текущий базовый каталог AppDomain. Остальное в основном проверяет корни путей и нормализацию путей.

16
ответ дан Simon Mourier 23 May 2017 в 12:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: