У меня есть веб-приложение.NET, использующее С# и SQL Server для части базы данных. Недавно я узнал о "проекте базы данных SQL Server" в VisualStudio, чтобы добавить мою схему SQL в мое CVS. Очень полезно! Кроме того, если я ошибаюсь в хранимой процедуре, например, решение не будет создано, что является удивительным.
Теперь, моя проблема. В моей БД есть несколько десятков хранимых процедур. В части С# я группирую вызовы хранимых процедур в классах, где пишу что-то похожее: ExecuteQuery("spMyStoredProcedure", SqlParamenter[]...)
. Как вы видите, я вроде как hardcode имя хранимой процедуры. Лучшим вариантом было бы создание констант, таких как:
private static const string SP_MY_STORED_PROCEDURE = "spMyStoredProcedure";
Но поскольку я использую только хранимую процедуру один раз, это почти то же самое, что и жесткое кодирование. Было бы очень приятно создать эти константы (имена хранимых процедур, параметры, имена таблиц, столбцы и т.д.) Из проекта SQL Server. На самом деле было бы еще лучше, если он автоматически генерирует код, чтобы вызвать эти хранимые процедуры, такие как методы С#, но константы для меня достаточно хороши :). Было бы неплохо, если бы я мог переименовать хранимые процедуры в моем SQL-Server-Project, чтобы визуальная студия правильно меняла свой код на С# или показывала ошибки сборки в вызове SP, если я удалю параметр из хранимой процедуры.
Я знаю, что в Visual Studio проект SQL генерирует DLL файл, но если я его проверю, он пуст, поэтому я не могу просто добавить ссылку в свой проект С#. Я потратил часы и часы на поиски и поиски в ней, но ничего не нашел. Я просто не могу поверить, что раньше никто не пытался сделать такую простую вещь. Это выглядит так естественно для меня, и реализовать такую функциональность должна быть кусок пирога для Microsoft, верно?. Я что-то упустил? Как бы вы решили это?
Вы можете сделать это, используя захватывающие файлы T4, которые могут генерировать код для нас!
Вы можете настроить файл .tt
который может выполнять поиск в папке, где хранятся ваши хранимые процедуры, извлекать список файлов, .sql
расширение .sql
от имен файлов и перебирать этот список для создания постоянных переменных. Slick!
Итак, в одном из ваших проектов С# из вашего решения (желательно в базе данных, если у вас есть многоуровневая архитектура приложения), добавьте файл StoredProceduresNames.tt, который будет содержать следующий код T4:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".generated.cs" #>
<#@ import namespace="System.IO" #>
namespace MyProject.Constants {
/// <summary>
/// Contains the names of the stored procedures of the application
/// </summary>
public static class StoredProceduresNames
{
<#
string storedProceduresFolder = "Stored Procedures"; //set the path to sp folder here...
string[] fileArray = Directory.GetFiles(Host.ResolvePath(storedProceduresFolder));
foreach(var filePath in fileArray){
string spName = Path.GetFileName(filePath).ToUpper().Replace(".SQL", "");
#>
public const string <#= spName #> = "<#= spName #>";
<#
}
#>
}
}
Возможно, вы захотите установить переменную storedProceduresFolder
относительно файла .tt
(я имею в виду, если файл.tt находится в проекте aС#, а ваши хранимые процедуры находятся в проекте базы данных, путь должен быть чем-то вроде ../MyProject.Database/Stored Procedures
.
Затем вы можете использовать сгенерированный файл в своем коде:
ExecuteQuery(MyProject.StoredProceduresNames.MY_STORED_PROCEDURE, SqlParamenter[]...)
Не стесняйтесь настраивать этот код по мере необходимости (условные обозначения кода, комментарии и т.д.).
ОБНОВЛЕНО: рассмотрите возможность использования Entity Framework для генерации кода
Вы также можете попытаться позволить Entity Framework генерировать код для вас не только для таблиц, но и для вызова хранимых процедур. Ознакомьтесь с этой статьей для получения дополнительной информации, используя Entity Framework, вы можете вызвать свои хранимые процедуры таким образом:
MyEntities context = new MyEntities();
context.CallMyStoredProcedure(123, "West");//call to stored procedure
Другое преимущество заключается в том, что результат хранимых процедур также строго типизирован.