使用SQL来linq where语句

本文关键字:where 语句 linq SQL 使用 | 更新日期: 2023-09-27 18:07:17

我的sp中有以下where语句:

            SELECT  h.HLDG_DATE,
                m.PTF_FIDEM_ID,
                m.PTF_Name,
                id.IDENTIFIER_NAME, 
                MIN(h.DESCRIPTION) DESCRIPTION,
                ii.SPEC_TABLE,
                m.PTF_CURRENCY, 
                id.IDENTIFIER_VALUE,
                h.CURRENCY,
                h.HLDG_QTY,
                MIN(h.CURRENT_PRICE) current_price,
                h.INSTRUMENT_ID
          FROM HOLDINGS_BREAKDOWN h
            LEFT JOIN FI_SYS_PTFIDX_LIST m on  (m.PTF_FIDEM_ID = h.PORTFOLIO_ID)
            LEFT JOIN inst_identifiers id on   (h.instrument_id = id.instrument_id)
            LEFT JOIN INST_CASH ic ON h.INSTRUMENT_ID = ic.INSTRUMENT_ID
            LEFT JOIN INST_FX_FORWARD iff ON h.INSTRUMENT_ID = iff.INSTRUMENT_ID
            LEFT JOIN INST_FX_SPOT ifs ON h.INSTRUMENT_ID = ifs.INSTRUMENT_ID
            JOIN INST_IDS ii ON h.INSTRUMENT_ID = ii.INSTRUMENT_ID
          WHERE h.PORTFOLIO_ID = 112
            AND h.HLDG_DATE >= '28 November 2014'
            AND  h.HLDG_DATE <= '31 December 2014'
            AND id.IDENTIFIER_NAME = (CASE WHEN ii.SPEC_TABLE 
                in ('INST_BOND','INST_EQUITY','INST_FUTURE') THEN 'ISIN'
                   WHEN ii.SPEC_TABLE ='INST_CASH' THEN 'XXX'   
                   WHEN ii.SPEC_TABLE = 'INST_INDEX_RETURN_SWAP' 
                    THEN 'BBG_UNIQUE' WHEN ii.SPEC_TABLE = 'INST_TOTAL_RETURN_SWAP'
                    THEN 'BBG_UNIQUE' ELSE 'STATESTREET'  END )
         GROUP BY h.HOLDING_PARAMS_ID,h.INSTRUMENT_ID, h.CURRENCY,id.IDENTIFIER_VALUE,h.HLDG_QTY,
                ii.SPEC_TABLE, h.HLDG_DATE,m.PTF_FIDEM_ID,m.PTF_Name,id.IDENTIFIER_NAME,m.PTF_CURRENCY 
         ORDER BY h.HLDG_DATE,Description  DESC

我已经在linq中做过了:

 where  h.PORTFOLIO_ID == Convert.ToInt16(PfID)
         &&     h.HLDG_DATE >=Convert.ToDateTime(  DTstart)
         &&     h.HLDG_DATE <= Convert.ToDateTime(DTend)

我正在为最后一个条件"case"而挣扎,你能帮我吗?

使用SQL来linq where语句

好吧,它可能不会生成相同的CASE语句,但是功能上的等价的是:

string[] isins = new [] {"I_BOND","I_EQUITY","I_FUTURE"}
...
where  h.PORTFOLIO_ID == Convert.ToInt16(PfID)
   &&  h.HLDG_DATE >= Convert.ToDateTime(DTstart)
   &&  h.HLDG_DATE <= Convert.ToDateTime(DTend)
   &&  id.IDENTIFIER_NAME == (
           inins.Contains(ii.SP_TABLE)            ? "ISIN" :
           ii.S_TABLE == "I_CASH"                 ? "CDB"  :
           ii.S_TABLE == "I_INDEX_RETURN_SWAP"    ? "BBG_UNIQUE"  :
           ii.S_TABLE == "INST_TOTAL_RETURN_SWAP" ? "BBG_UNIQUE"  :
           "STTREET");

另一种选择是将该映射放在表中,并执行JOIN

还请注意,您可能必须在Linq语句之外执行Convert.ToXXX调用,并将结果存储为变量,以便Linq将其作为常量处理。

你可以这样做

var tables = new List<string>{"INST_BOND","INST_EQUITY","INST_FUTURE"};
.........
.. id.IDENTIFIER_NAME = tables.Contains(ii.SPEC_TABLE) 
                         ? "ISIN"
                         : ii.SPEC_TABLE == "INST_CASH" 
                            ? id.IDENTIFIER_NAME == "XXX"
                            :ii.SPEC_TABLE == "INST_INDEX_RETURN_SWAP"
                              ? "BBG_UNIQUE"
                               .........

这将是字面翻译,但你应该创建一个逻辑结构,如dictionary,并在执行linq后分配该值。如果您想使用linq,那么您需要有一个查找表,并与ii.SPEC_TABLE

连接

switch语句是不允许在linq2sql据我所知(请纠正我,如果这是错误的)。这意味着,没有直接的方法来编写语句,它将被转换为SQL-Case。

我建议只使用三元操作符?:来构建语句。这不是最漂亮的方式,但在这种情况下完全可以。

(顺便说一句,另一个技巧:在linq语句之外转换日期。当您这样做时,语句将被。net框架转换,并且只有转换后的值将传递给SQL,而不是整个转换操作,这是相当昂贵的)