Каждый раз, когда мой сайт запускается, я хочу запускать X скриптов. Последнее, что сделает метод Startup.Configure
, это вызовет мой метод:
DbInitializer.Initialize(context);
if (env.IsDevelopment()) {
scopeFactory.SeedData(Configuration.GetConnectionString("AlmanacSQL"));
}
Вот мой метод:
public static void SeedData(this IServiceScopeFactory scopeFactory, string connectionString) {
using (var serviceScope = scopeFactory.CreateScope()) {
var context = serviceScope.ServiceProvider.GetService<AlmanacDb>();
foreach (var f in di.GetFiles("*.sql").OrderBy(x => x.Name)) {
context.Database.ExecuteSqlQuery(File.ReadAllText(f.FullName));
}
}
}
Он отлично работает, пока не попытается запустить первый скрипт и не выдаст ошибку:
Оператор CREATE/ALTER PROCEDURE должен быть первым в пакете запросов.
Я видел этот ответ здесь, но он относится к миграции. Другие ответы не помогли в моей ситуации. Я просто хочу запускать их каждый раз. Скрипты будут достаточно умны, чтобы не дублировать то, что они делают.
Я попытался удалить операторы GO
, но это не помогло.
Есть ли способ выполнить SQL-скрипты в Entity Framework Core, которые содержат GO
операторов? Есть ли какие-то настройки, которые я могу поменять местами в SQL или EF? Есть ли более глубокий базовый контекст, подобный следующему, который я использовал в EF 6?
public ObjectContext UnderlyingContext { get { return ((IObjectContextAdapter)this).ObjectContext; } }
EDIT Сразу после того, как я вернулся к своему коду, я решил, что должен хотя бы показать скрипт:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'GetEnumTriplet') AND type IN (N'P', N'PC'))
DROP PROCEDURE GetEnumTriplet
GO
CREATE PROCEDURE GetEnumTriplet
(
@Enumeration NVARCHAR(25),
@EnumName NVARCHAR(25) = NULL,
@EnumValue INT = NULL
)
AS
BEGIN
DECLARE @SQL NVARCHAR(250)
DECLARE @PDs NVARCHAR(100) = N'@OutValue INT OUTPUT, @OutDisplay NVARCHAR(30) OUTPUT, @OutName NVARCHAR(25) OUTPUT'
DECLARE @Value INT = 0
DECLARE @Display NVARCHAR(30)
DECLARE @Name NVARCHAR(25)
IF (@EnumName IS NOT NULL)
SET @SQL = 'SELECT @OutValue = e.ID, @OutDisplay = e.Name, @OutName = e.EnumName FROM ref.' + @Enumeration + ' AS e WHERE e.EnumName = ' + '''' + @EnumName + ''''
ELSE IF (@EnumValue IS NOT NULL)
SET @SQL = 'SELECT @OutValue = e.ID, @OutDisplay = e.Name, @OutName = e.EnumName FROM ref.' + @Enumeration + ' AS e WHERE e.ID = ' + CAST(@EnumValue AS NVARCHAR)
EXECUTE sp_executesql
@SQL, @PDs, @OutValue = @Value OUTPUT, @OutDisplay = @Display OUTPUT, @OutName = @Name OUTPUT;
-- Test Content
SELECT
1 AS ID,
@Value AS Value,
@Display AS DisplayName,
@Name AS KeyName,
@Enumeration AS EnumerationName
/*
GetEnumTriplet 'ProjectStatus', 'In Progress' -- Wrong
GetEnumTriplet 'ProjectStatus', 'InProgress', 3 -- Will default to looking up InProgress and skip looking up 3
GetEnumTriplet 'ProjectStatus', 'InProgress'
GetEnumTriplet 'ProjectStatus', NULL, 2
*/
END
GO
GO
бесполезен при запуске скрипта через код C#. эта проблема не решает вашу проблему, она сможет объяснить, что происходит неправильно. - person Smit   schedule 21.06.2017