Можно ли получить строку подключения внутри шаблона генерации DDL в VS2010? - PullRequest
2 голосов
/ 19 февраля 2010

Я играю с созданием шаблона T4 для процесса «Шаблон генерации DDL» (сначала модель) в Visual Studio 2010 RC. Можно ли получить строку подключения, связанную с этим процессом? Если я щелкну правой кнопкой мыши на файле .edmx и выберу «Создать базу данных из модели ...», у меня будет возможность выбрать подключение для передачи данных. Эта строка соединения сохраняется в app.config (при условии, что опция включена). Поэтому мне интересно, возможно ли получить эту строку подключения внутри шаблона T4. Я хотел бы генерировать другую информацию из шаблона на основе строки подключения.

В более общем смысле, возможно ли получить какую-либо контекстную информацию в этой ситуации? Пока единственное, что я успешно извлек, - это имя поставщика данных .NET.

Примечание. Я изучил идеи, предложенные Крейгом, но получаю только название IDE (devenv.exe), что, вероятно, означает, что я просто что-то делаю не так.

Ответы [ 3 ]

4 голосов
/ 06 апреля 2012

На случай, если это кому-нибудь поможет, вот фрагмент, который я создал для чтения строки подключения Entity Framework изнутри T4.Вы передаете ему имя модели (которое также является именем строки подключения).Он находит и анализирует только тот бит соединения, который мне нужен.Он также выдает полезные ошибки, когда это не удается.

Для использования:

A.Вставьте его вверху шаблона, если вы еще не ссылаетесь на эти сборки:

<#@ assembly name="EnvDTE" #>
<#@ assembly name="System.Configuration" #>

B.Вставьте этот уродливый (но компактный) код в конец вашего шаблона:

<#+
string GetEFConnectionString(string modelName)
{
    string file = null, key = "provider connection string=\"";
    foreach (EnvDTE.ProjectItem item in ((EnvDTE.Project)((Array)((EnvDTE.DTE)((IServiceProvider)this.Host).GetService(typeof(EnvDTE.DTE))).ActiveSolutionProjects).GetValue(0)).ProjectItems)
        if (System.Text.RegularExpressions.Regex.IsMatch(item.Name, "(app|web).config", System.Text.RegularExpressions.RegexOptions.IgnoreCase)) {
            file = item.get_FileNames(0); break;
        }
    if (file == null) throw new Exception("config file could not be found");
    var config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(new System.Configuration.ExeConfigurationFileMap() { ExeConfigFilename = file }, System.Configuration.ConfigurationUserLevel.None);
    var cn = config.ConnectionStrings.ConnectionStrings[modelName];
    if (cn == null) throw new Exception(modelName + " connection string could not be found");
    string s = cn.ConnectionString;    
    int pos = s.IndexOf(key,StringComparison.OrdinalIgnoreCase);    
    if (pos<0) throw new Exception("could not find value '" + key + "' inside connection string");
    pos += key.Length;
    int pos2=s.IndexOf('"',pos);
    if (pos2 < 0) throw new Exception("could not find ending \" in connection string");
    return s.Substring(pos,pos2-pos);
}
#>

C.Используйте это так:

using(var connection = new SqlConnection(GetEFConnectionString("Database"))) {
    ..
}    
3 голосов
/ 01 марта 2010

Я разместил свой вопрос на одном из форумов MSDN и получил ответ от Линчжи Сунь, который указал мне пару ссылок на skysanders.net.Вторая из этих ссылок имеет очень хороший пример получения файла app / web.config и, в частности, той части, которую я хотел, строк подключения.Он не дает никакой информации о конкретной строке подключения для сценария, который я описал в исходном вопросе, но это достаточно близко подходит для меня.

1 голос
/ 19 февраля 2010

Ну, строка подключения EF всегда будет иметь то же имя, что и модель, верно? Строка подключения к БД будет встроена в строку подключения EF. Поэтому я бы сказал, что вы сможете получить его, по крайней мере, косвенно, через строку подключения EF.

Поскольку вы не работаете в сборке, необходимо указать имя файла конфигурации.

Так было бы что-то вроде:

var config = ConfigurationManager.OpenExeConfiguration(name);
var cs = config.ConnectoinStrings[modelName];

Обратите внимание, что name здесь должно быть именем EXE. Но в IDE ваш файл конфигурации будет называться App.config, а не MyApp.dll.config. Поэтому вам, возможно, придется поиграться с этим, чтобы заставить его работать - попробуйте использовать «App» в качестве имени EXE-файла!

В худшем случае откройте его как файл и затем используйте диспетчер конфигурации.

...