EF6-导入功能时出现问题(代码优先)

时间:2020-07-10 07:20:44

标签: c# entity-framework entity-framework-6 ef-code-first

我使用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

我的目标是在此自定义函数上进行内部联接以执行“包含”(因为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));
}

感谢您的帮助! 抱歉语法错误,英语不是我的母语:)

0 个答案:

没有答案