EF6 - Проблема при импорте функции (сначала код) - PullRequest
0 голосов
/ 10 июля 2020

Я использую Entity Framework 6 (сначала код) и пытаюсь импортировать настраиваемую SQL функцию «StringSplitDecimal»:

CREATE FUNCTION StringSplitDecimal
(   
    @ids VARCHAR(MAX)
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT CAST([value] AS DECIMAL(10,0)) as [Value] FROM STRING_SPLIT(@ids, ';')
)
GO

Моя цель - выполнить внутреннее соединение этой настраиваемой функции, чтобы сделать a "Содержит" (потому что WHERE IN настолько медленный), например:

.Join
(
    dbContext.StringSplitDecimal(string.Join(";", randomIds)),
    randomTable => randomTable.RandomId,
    split => split,
    (randomTable, _) => new { randomTable }
)

(Примечание: этот код подходит для EDMX, и очень быстро!)

Но когда я выполнить функцию с моим контекстом, запрос SQL:

exec sp_executesql N'SELECT 
    [Extent1].[Value] AS [C1]
    FROM [dbo].[StringSplitDecimal](@ids) AS [Extent1]',N'@ids nvarchar(4000)',@ids=N'12'

Итак, у меня есть ошибка с EF: «Запрос попытался вызвать« OuterApply »по вложенному запросу, но« OuterApply »сделал нет соответствующих ключей. "

Мой вопрос:« Как мне указать EF правильно назвать поле, не [C1], а [Value] »?

Мой код для импорта функции :

public void Apply(EntityContainer item, DbModel model)
{
    var rowType = RowType.Create(
        new[]
        {
            EdmProperty.Create("Value", TypeUsage.CreateDecimalTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Decimal)))
        }, null);
    var returnEdmType = rowType.GetCollectionType();
    var returnParameters = new List<FunctionParameter>
    {
        FunctionParameter.Create("Value", returnEdmType, ParameterMode.ReturnValue)
    };

    var functionPayload = new EdmFunctionPayload
    {
        Schema = "dbo",
        Parameters = new[] {
            FunctionParameter.Create("ids", model.ProviderManifest.GetStoreType(TypeUsage.CreateStringTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, false)).EdmType, ParameterMode.In)
        },
        ReturnParameters = returnParameters,
        IsComposable = true
    };

    var storeFunctionDefinition = EdmFunction.Create("StringSplitDecimal", "TestContext", DataSpace.SSpace, functionPayload, null);
    model.StoreModel.AddItem(storeFunctionDefinition);


    functionPayload = new EdmFunctionPayload
    {
        Parameters = new[] {
            FunctionParameter.Create("ids", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In),
        },
        ReturnParameters = new[] {
            FunctionParameter.Create("Value", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Decimal).GetCollectionType(), ParameterMode.ReturnValue),
        },
        IsComposable = true,
        IsFunctionImport = true,
        EntitySets = new EntitySet[1]
    };

    var importFunctionDefinition = EdmFunction.Create("StringSplitDecimal", model.ConceptualModel.Container.Name, DataSpace.CSpace, functionPayload, null);
    model.ConceptualModel.Container.AddFunctionImport(importFunctionDefinition);

    model.ConceptualToStoreMapping.AddFunctionImportMapping(
        new FunctionImportMappingComposable(importFunctionDefinition, storeFunctionDefinition, new FunctionImportResultMapping(), model.ConceptualToStoreMapping));
}

Спасибо за помощь! Извините за грамматические ошибки, английский sh не мой родной язык :)

...