Linq语句与存储过程返回列值

时间:2015-03-13 03:30:30

标签: c# linq entity-framework entity-framework-6

我有一个linq语句从表中获取几列,然后最后一列是从存储过程返回的值。存储过程返回varchar(max)值,因为它正在执行一些递归查找,并且可能会很长。

对于下面的代码,我使用“CalculatedValueSproc”作为填充名为“CalculatedValue”的变量的存储过程的名称,该变量只是一个字符串。

var users = 
    (from u in _db.Users
        where u.Deleted == false
        orderby u.Name
         select new User
         {
             Id = u.Id,
             Name = u.Name,
             CalculatedValue = _db.CalculatedValueSproc(u.Id),
         }).ToList();

执行此操作时出错:

  

LINQ to Entities无法识别方法'System.Data.Entity.Core.Objects.ObjectResult 1[System.String] CalculatedValueSproc(System.Nullable 1 [System.Int32])'方法,并且此方法无法转换为商店表达式。< / p>

不知道我哪里出错了,但感谢任何帮助。谢谢。

罗伯特

3 个答案:

答案 0 :(得分:1)

它试图将CalculatedValue = _db.CalculatedValueSproc(u.Id)转换为SQL语句,但它不能。但是你可以在它是物化列表而不是SQL语句之后调用它。执行ToList()将触发SQL并获得结果,然后允许您为每条记录调用SPROC。

我添加的SELECT()函数正在使用完整的POCO,并且不必转换为SQL语句。

试试这个:

var users = 
(from u in _db.Users
    where u.Deleted == false
    orderby u.Name).ToList().
Select( u => new User
     {
         Id = u.Id,
         Name = u.Name,
         CalculatedValue = _db.CalculatedValueSproc(u.Id),
     });

答案 1 :(得分:0)

就像你不能在一个sql查询中直接用列值调用sp。 您可以将结果分开如下:

var users = 
    (from u in _db.Users
        where u.Deleted == false
        orderby u.Name
         select new User
         {
             Id = u.Id,
             Name = u.Name,
             CalculatedValue = null,
         }).ToList();

foreach (var user in users)
{
  user.CalculatedValue = _db.CalculatedValueSproc(u.Id);
}

答案 2 :(得分:0)

当我遇到这样的问题时,这些步骤对我有所帮助:

  1. 使用XML打开您的EDMX模型,找到您的功能并更改其属性如下:
  2. <Function Name="CalculatedValueSproc" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" ReturnType="varchar">
      <Parameter Name="Id" Type="numeric" Mode="In" />
    </Function>
    

    请注意,IsComposable属性设置为true,ReturnType属性是函数返回的类型,在您的情况下应该是varchar。

    1. 保存EDMX文件并重建项目。

    2. 将您的函数添加到dbContext文件中:

      public partial class YourEntities
      {
          [DbFunction("YourModel.Store", "CalculatedValueSproc")]
          public string CalculatedValueSproc(int? Id)
          {
              throw new NotSupportedException("Direct calls are not supported.");
          }
      }
      
    3. 删除这些代码行(如果它们在dbContext文件中):

      public virtual ObjectResult<Nullable<string>> CalculatedValueSproc(Nullable<int> Id)
      {
          var IdParameter = Id.HasValue ?
          new ObjectParameter("Id", Id) :
          new ObjectParameter("Id ", typeof(int));
      
          return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable< string >>("CalculatedValueSproc", Id);
      

      }

    4. 保存EDMX文件并重建项目。