在group join linq查询中将字符串转换为十进制 [英] Convert string to decimal in group join linq query

查看:148
本文介绍了在group join linq查询中将字符串转换为十进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须加入两个表,但只返回第二个表中的记录,其中与第一个表中的记录相关联的所有记录的值相同。



p pre $ p $ db pre pre pre pre pre pre pre pre.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
其中p.Value =(select sum(cast(n.Value as decimal(12, 2)))从TN,其中Key = p.Key)


解决方案

p>您可以通过创建一些模型定义的函数来实现。请参阅此链接:在至少实体框架4中创建和调用模型定义的函数



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



打开您的.EDMX文件作为XML,以便您可以编辑文本。



将您的自定义转换功能添加到CSDL内容部分的Scheme部分

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

新功能:

 < Function Name =ConvertToInt32ReturnType =Edm.Int32> 
< Parameter Name =myStrType =Edm.String/>
< DefiningExpression>
CAST(myStr AS Edm.Int32)
< / DefiningExpression>
< / Function>
< Function Name =ConvertToDecimalReturnType =Edm.Decimal>
< Parameter Name =myStrType =Edm.String/>
< DefiningExpression>
CAST(myStr AS Edm.Decimal(12,2))
< / DefiningExpression>
< / Function>

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



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

  //注意:将EFTestDBModel命名空间更改为模型名称
[System.Data.Objects.DataClasses.EdmFunction(EFTestDBModel,ConvertToInt32)]
public static int ConvertToInt32(string myStr)
{
抛出新的NotSupportedException(不支持直接调用);
}

//注意:将EFTestDBModel命名空间更改为模型名称
[System.Data.Objects.DataClasses.EdmFunction(EFTestDBModel,ConvertToDecimal )]
public static decimal ConvertToDecimal(string myStr)
{
抛出新的NotSupportedException(不支持直接调用);
}

最后,调用您的新方法:

  using(var ctx = new EFTestDBEntities())
{
var results = from x in ctx.MyTables
让TheTotal = ctx.MyTables.Sum(y => ConvertToDecimal(y.Price))
选择新
{
ID = x.ID,
//以下三个值存储为DB
Price = ConvertToDecimal(x.Price),
Quantity = ConvertToInt32(x.Quantity),
Amount = x.Amount,
TheTotal
};
}

您的具体示例如下所示:

  from p in db.TPs 
在db.TNs中连接n在p.Key上的
等于n.Key
其中( ConvertToDecimal(p.Value)==
db.TNs.Where(nn => nn.Key == p.Key).Sum(nn => ConvertToDecimal(kk.Value)))


I have to join two tables but to return only those records in second table where sum of 'Value' of all records associated with the record in first table is the same.

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)))

I'm using Entity Framework Code-First.

Of course, Linq complains

LINQ to Entities does not recognize the method 'System.Decimal Parse(System.String)' method

Tables are huge and I must reduce output, so doing this conversion on the client side is not possible. Column type conversion is also not an option.

The SQL query is:

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)

解决方案

You can do this by creating some Model-Defined Functions. See this link: Creating and Calling Model-Defined Functions in at least Entity Framework 4

Specifically, to add some functions to convert string to decimal and string to int, follow these steps:

Open your .EDMX file as XML so you can edit the text.

Add your custom conversion functions to the "CSDL content" section's "Scheme" section

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

New functions:

<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>

(Modify the precision of the above Edm.Decimal to suit your needs.)

Then, in your c# code you need to create the corresponding static methods which you can store in a static class:

// 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.");
}

Finally, to make calls to your new methods:

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
                  };
}

Your specific example would look like this:

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)))

这篇关于在group join linq查询中将字符串转换为十进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆