我使用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));
}
感谢您的帮助! 抱歉语法错误,英语不是我的母语:)