使用Database.SqlQuery从Entity Framework Code First调用存储过程不起作用

时间:2015-02-26 17:01:57

标签: c# entity-framework stored-procedures entity-framework-6

我正在尝试从DbContext调用存储过程,但是我在生成的SQL上收到错误。 EF生成的TSQL有这个错误:

  

参数化查询需要参数...,它未提供

如何修复EF查询以创建对存储过程的正确调用?

我的代码看起来像这样。这很长但很简单。它首先声明参数名称和存储过程名称。然后使用DbContextDatabase.SqlQuery使用已创建的SqlParamter调用存储过程。最后,它显示了此调用生成的SQL。

const string PayerId = "@PayerId";
const string ProviderId = "@ProviderId";
const string LineOfBusinessId = "@LineOfBusinessId";
const string PracticeLocationId = "@PracticeLocationId";
const string ClinicalCodingCategoryId = "@ClinicalCodingCategoryId";
const string FacilityName = "@FacilityName";
const string FacilityType = "@FacilityType";
const string ServiceDate = "@ServiceDate";
const string MilesFromPracticeLocation = "@MilesFromPracticeLocation";
const string GetPossibleSiteofServiceName = "getPossibleSiteofService";

var payerId = new Guid("5a4a16c3-d352-e411-80db-00155d66b519"); 
var providerId = new Guid("89516ad4-D852-E411-80DB-00155D66B519");
var lineOfBusinessId = new Guid("a2b3bcf3-9ab3-e311-80c3-00155d66cdf0"); 
var practiceLocationId = new Guid("36561da7-d852-e411-80db-00155d66b519"); 
var clinicalCodingCategoryId = new Guid("d541b72f-7ca3-e411-80db-00155d66b519");
string facilityName = null;
string facilityType = null;
Nullable<DateTime> serviceDate = null;
var milesFromPracticeLocation = 20;

using (var context = new AnalyticContext())
{
    var payerIdParameter = new SqlParameter(PayerId, payerId);
    var providerIdParameter = new SqlParameter(ProviderId, providerId);
    var lineOfBusinessIdParameter = new SqlParameter(LineOfBusinessId, lineOfBusinessId);
    var practiceLocationIdParameter = new SqlParameter(PracticeLocationId, practiceLocationId);
    var clinicalCodingCategoryIdParameter = new SqlParameter(ClinicalCodingCategoryId, clinicalCodingCategoryId);
    var facilityNameParameter = new SqlParameter(FacilityName, facilityName);
    var facilityTypeParameter = new SqlParameter(FacilityType, facilityType);
    var serviceDateParameter = new SqlParameter(ServiceDate, serviceDate);
    var milesFromPracticeLocationParameter = new SqlParameter(MilesFromPracticeLocation, milesFromPracticeLocation);

    var data = context.Database
                   .SqlQuery<PossibleSiteofService>(GetPossibleSiteofServiceName, payerIdParameter, 
                        providerIdParameter, lineOfBusinessIdParameter, 
                        practiceLocationIdParameter, 
                        clinicalCodingCategoryIdParameter, 
                        facilityNameParameter, facilityTypeParameter, 
                        serviceDateParameter, milesFromPracticeLocationParameter)
                   .FirstOrDefault();
            }

生成的SQL代码:

exec sp_executesql 
N'getPossibleSiteofService',
N'@PayerId uniqueidentifier,
@ProviderId uniqueidentifier,
@LineOfBusinessId uniqueidentifier,
@PracticeLocationId uniqueidentifier,
@ClinicalCodingCategoryId uniqueidentifier,
@FacilityName nvarchar(4000),
@FacilityType nvarchar(4000),
@ServiceDate nvarchar(4000),
@MilesFromPracticeLocation int',
@PayerId='5A4A16C3-D352-E411-80DB-00155D66B519',
@ProviderId='89516AD4-D852-E411-80DB-00155D66B519',
@LineOfBusinessId='A2B3BCF3-9AB3-E311-80C3-00155D66CDF0',
@PracticeLocationId='36561DA7-D852-E411-80DB-00155D66B519',
@ClinicalCodingCategoryId='D541B72F-7CA3-E411-80DB-00155D66B519',
@FacilityName=default,
@FacilityType=default,
@ServiceDate=default,
@MilesFromPracticeLocation=20

存储过程非常简单:

[dbo].[getPossibleSiteofService]
    @PayerId UniqueIdentifier, --Required
    @ProviderId UniqueIdentifier, --Required
    @LineOfBusinessId UniqueIdentifier, --Required
    @PracticeLocationId UniqueIdentifier, --Required
    @ClinicalCodingCategoryId UniqueIdentifier, --Required
    @FacilityName varchar(255) = NULL, --Optional
    @FacilityType varchar(255) = NULL, --Optional
    @ServiceDate DateTime = NULL, --Optional Will Default to CURRENT DTM
    @MilesFromPracticeLocation int = NULL --Optional
AS
....

2 个答案:

答案 0 :(得分:-1)

去年我遇到了类似的问题,并找到了我的解决方案:

这个问题的解决方案(在我的情况下是)

var stuff = db.Database.SqlQuery<SomeEntityType>(query, parms);

其中query是一个插入了参数的字符串,如@Name等.parms变量是一个SQLParameters列表。 SQL不像通用列表......

SQL必须有一个SQLParameters数组和object [],而不是泛型类型列表。

var stuff = db.Database.SqlQuery<SomeEntityType>(query, parms.ToArray());

答案 1 :(得分:-1)

将您的存储过程添加到EDMX / Model,就像添加表一样 然后,您可以使用上下文对象

访问存储过程作为函数

你需要这样做 打开'EDMX / Model'文件 然后打开模型浏览器' 并花费“存储过程”节点 右键单击您的过程,然后单击“添加函数导入”

现在您可以像

一样访问您的sp
context.getPossibleSiteofService(payerId, providerId, lineOfBusinessId, clinicalCodingCategoryId....., milesFromPracticeLocation)

**当使用SP作为函数时,不需要SQL参数,您可以直接使用C#变量,因为您已经赋值。