在组连接linq查询中将字符串转换为十进制

时间:2012-08-31 13:10:06

标签: c# sql linq entity-framework

我必须加入两个表但只返回第二个表中的那些记录,其中与第一个表中的记录相关的所有记录的“值”总和是相同的。

from p in db.TPs
join n in db.TNs
on p.Key equals n.Key
where (decimal.Parse(p.Value) == db.TNs.Where( nn => nn.Key == p.Key )
                                       .Sum( nn=> decimal.Parse(kk.Value)))

我正在使用Entity Framework Code-First。

当然,Linq抱怨

  

LINQ to Entities无法识别方法'System.Decimal   Parse(System.String)'方法

表很大,我必须减少输出,因此无法在客户端进行此转换。列类型转换也不是一种选择。

SQL查询是:

select * from TP as p
join * from TN as n on n.Key = p.Key
where p.Value = (select sum(cast(n.Value as decimal(12,2))) from TN where Key = p.Key)

3 个答案:

答案 0 :(得分:10)

您可以通过创建一些模型定义函数来完成此操作。请看这个链接:Creating and Calling Model-Defined Functions in at least Entity Framework 4

具体来说,要添加一些函数将字符串转换为十进制并将字符串转换为int,请按照下列步骤操作:

以XML格式打开.EDMX文件,以便编辑文本。

将自定义转化功能添加到“CSDL内容”部分的“方案”部分

<edmx:ConceptualModels>
<Schema....>

新功能:

<Function Name="ConvertToInt32" ReturnType="Edm.Int32">
  <Parameter Name="myStr" Type="Edm.String" />
  <DefiningExpression>
    CAST(myStr AS Edm.Int32)
  </DefiningExpression>
</Function>
<Function Name="ConvertToDecimal" ReturnType="Edm.Decimal">
  <Parameter Name="myStr" Type="Edm.String" />
  <DefiningExpression>
    CAST(myStr AS Edm.Decimal(12, 2))
  </DefiningExpression>
</Function>

(修改上述Edm.Decimal的精度以满足您的需要。)

然后,在您的c#代码中,您需要创建可以存储在静态类中的相应静态方法:

// NOTE: Change the "EFTestDBModel" namespace to the name of your model
[System.Data.Objects.DataClasses.EdmFunction("EFTestDBModel", "ConvertToInt32")]
public static int ConvertToInt32(string myStr)
{
    throw new NotSupportedException("Direct calls are not supported.");
}

// NOTE: Change the "EFTestDBModel" namespace to the name of your model
[System.Data.Objects.DataClasses.EdmFunction("EFTestDBModel", "ConvertToDecimal")]
public static decimal ConvertToDecimal(string myStr)
{
    throw new NotSupportedException("Direct calls are not supported.");
}

最后,要调用新方法:

using (var ctx = new EFTestDBEntities())
{
    var results = from x in ctx.MyTables
                  let TheTotal = ctx.MyTables.Sum(y => ConvertToDecimal(y.Price))
                  select new
                  {
                      ID = x.ID,
                      // the following three values are stored as strings in DB
                      Price = ConvertToDecimal(x.Price),
                      Quantity = ConvertToInt32(x.Quantity),
                      Amount = x.Amount,
                      TheTotal
                  };
}

您的具体示例如下所示:

from p in db.TPs
join n in db.TNs
on p.Key equals n.Key
where (ConvertToDecimal(p.Value) == 
        db.TNs.Where( nn => nn.Key == p.Key ).Sum( nn=> ConvertToDecimal(kk.Value)))

答案 1 :(得分:0)

不幸的是,LINQ to SQL无法创建带有字符串到十进制转换的SQL表达式。

如果你想这样做,你必须使用以下方法执行自己的查询:

ExecuteStoredQuery

答案 2 :(得分:0)

您可以将string转换为decimal,而不是将decimal转换为string。如果其他人不这样做,这种方法可行。