C# 获得;资料来源;LINQ查询和序列化为字符串的
这个问题与当前正在进行渐进式维护的实时应用程序有关。请允许我花几行解释它是如何工作的 该应用程序使用182个SQL查询扫描从大文本文件导入的大型数据集,根据设计,这些SQL查询存储在数据库中,并经过加密。主要的缺点是,由于SQL Server和MySQL的语法差异,我们正在为它们维护单独的查询 当前允许root用户查看和编辑SQL文本。查看SQL以了解查询在某些特定情况下的工作方式(很少要求我们修改它们)是一项要求 为了克服DBMS的差异,我尝试将这些查询转换为LINQ,这本身是一项困难的任务,因为它们很复杂。但我的问题是另一个 考虑到我正在创建一个C# 获得;资料来源;LINQ查询和序列化为字符串的,c#,linq,entity-framework,C#,Linq,Entity Framework,这个问题与当前正在进行渐进式维护的实时应用程序有关。请允许我花几行解释它是如何工作的 该应用程序使用182个SQL查询扫描从大文本文件导入的大型数据集,根据设计,这些SQL查询存储在数据库中,并经过加密。主要的缺点是,由于SQL Server和MySQL的语法差异,我们正在为它们维护单独的查询 当前允许root用户查看和编辑SQL文本。查看SQL以了解查询在某些特定情况下的工作方式(很少要求我们修改它们)是一项要求 为了克服DBMS的差异,我尝试将这些查询转换为LINQ,这本身是一项困难的任务,
IQuery
接口来运行来自EFDbContext
的特定查询和扫描参数化,我仍然希望保留谓词的可读的、可能格式化的字符串表示形式,以显示根用户(否则,我们的功能分析师将不得不期望我的邮件带有LINQ源代码)
我做了一些家庭作业。我读到了关于将
表达式
树字符串化的可能性,这是一个很好的起点。问题是,创建接口方法表达式自己找到了答案。一旦找到了答案,就变得微不足道了
选择1
归功于@xanatos
使用LINQ to Entities中的IQueryable.ToString()
方法来获取已格式化的确切SQL查询
- 赞成者:这正是将要启动的查询
- 缺点:由于使用了多个别名或嵌套的
SELECT
s组合,因此查询的可读性较差
选择2
使用IQueryable.expression
属性获取查询表达式。然后,如何字符串化expression的主题我通常使用字符串联接。可以将linq的输出设置为ToArray()方法。因此,这通常是有效的:string.join(“,”,…ToArray())。我使用逗号来生成输出CSV,但您可以在联接中使用任何字符,甚至空格。您不能简单地保存IQueryable
的ToString()
?实体框架在ToString()
中显示它将执行的查询。@jdweng您确定ToArray()吗不将结果集返回到数组中?这不是我想要的want@xanatos该死!我不知道ToString()返回带有标记参数和更改的表名的精确查询。它应该是一个候选答案表名几乎都是经过编辑的我在编写的一些测试查询中没有这个问题…我使用.ToString()
的唯一问题是生成的查询不适合“人类使用”…它通常非常复杂,通常基于一个SELECT*FROM SELECT*FROM SELECT*FROM…UNION SELECT*FROM
,因此具有多层次和多个联合around@xanatos我已经修正了我的答案。我使用了错误的措辞我相信没有,那是一个别名…EF为所有表名提供别名…你从
转到,然后您将看到它是[dbo].[SomeTable]中的,因为[Extent1]
Yeah EF倾向于在任何地方使用别名-您可以执行一些正则表达式解析,并应用一些查找和替换来简化事情
IQuery theQueryToRun;
var query = from SectionA a in dataContext.sectionA
join SectionD b in dataContext.sectionB on a.A03 equals b.A03
.... join ....
query = query.Where(theQueryToRun.GetWhereClause(...));
query = query.OrderBy(theQueryToRun.GetOrderByClause());
return query.ToList();
SELECT a.a01,a.a01a,a.a01b,a.a02,a.a03,a11,a12,a12a,a12b,a12c,a21,a22,a23,a24,
a25,a31,
a31a,a31b,a32,a33,a33a,a33b,a33c,a34,a41,a42,a43,a51,a52,a53,a54,a54a,
a54b,a54c,b11,b12,b13,b14,b15,z0,a.prog,a.utente,c11,d11,d13,d14,d14a,
d14b,d14c,d15,d16,d17,d18,d19,d21,d22,d23,d31,d32,d41,d42,d43,d44,d45,z1
FROM sezione_a a
INNER JOIN sezione_d d
ON a.a03 = d.a03
AND a.utente = d.utente
WHERE ( ( a.a42 IN ( '0', '1', '' )
AND d.d21 IN(SELECT codice
FROM sottogruppi
WHERE flagpf = 1) )
AND ( d.d11 IS NOT NULL
AND d.d11 <> '' )
AND d.d45 IN( '1', '2' )
AND ( ( d.d18 >= '19000101'
AND d.d18 <= a.a21 )
AND ( d.d43 >= '19000101'
AND d.d43 <= a.a21 )
AND d.d43 >= d.d18 )
AND ( Date_add(Str_to_date(d.d43, '%Y%m%d'), INTERVAL 10 year) >
Str_to_date(a.a21, '%Y%m%d')
AND Date_add(Str_to_date(d.d43, '%Y%m%d'), INTERVAL 10 year) <
Now() ) )
AND ( ( a.a21 BETWEEN '@@datamin' AND '@@datamax' )
AND a.utente = @@user
AND a.a52 NOT IN @@a52 )
ORDER BY a.a11 ASC,d.d11 ASC
public IList<QueryRow> Run(Models.auitool2014Entities dataContext, int aUserId, DateTime? dataInizioControllo, DateTime? dataFineControllo, string[] a52Exclude, bool codifiche2014, out long totalCount)
{
string sysdate10String = DateTime.Now.AddYears(-10).ToString("yyyyMMdd", CultureInfo.InvariantCulture);
var inner = codifiche2014 ?
from Sottogruppo sg in dataContext.sottogruppi where sg.flagpf select sg.codice :
from Sottogruppo2015 sg in dataContext.sottogruppi2015 where sg.flagpf select sg.codice;
var q = dataContext.sezione_a.Join(
dataContext.sezione_d,
a => new { A03 = a.A03, User = a.utente },
d => new { A03 = d.A03, User = d.utente },
(a, d) => new SezioneJoin { A = a, D = d }
)
.Where(x =>
x.A.utente == aUserId && //Flusso utente
new string[] { "0", "1", String.Empty }.Contains(x.A.A42) && // A42 IN (0,1,'')
inner.Contains(x.D.D21) && //D.D21 IN (SELECT CODICE FROM SOTTOGRUPPPI.A..A. WHERE FLAGPF = 1)
(x.D.D11 != null && x.D.D11 != String.Empty) && //D11 IS NOT NULL AND D11 <> ''
new string[] { "1", "2" }.Contains(x.D.D45) && //D45 IN ('1','2')
(
(x.D.D18.CompareTo("19000101") >= 0 && x.D.D18.CompareTo(x.A.A21) <= 0) && //D18 >= '1900101' AND D18 <= A21
(x.D.D43.CompareTo("19000101") >= 0 && x.D.D43.CompareTo(x.D.D18) >= 0) // D43 >= '19000101' AND D43 >= D18
) &&
x.D.D43.CompareTo(sysdate10String) < 0 // D43 <= (SYSDATE() - 10 YEARS)
);
if (dataInizioControllo != null)
{
string dataInzio = dataInizioControllo.Value.ToString("yyyyMMdd");
q = q.Where(x => x.A.A21.CompareTo(dataInzio) >= 0);
}
if (dataFineControllo != null)
{
string dataFine = dataFineControllo.Value.ToString("yyyyMMdd");
q = q.Where(x => x.A.A21.CompareTo(dataFine) <= 0);
}
if (a52Exclude != null)
q = q.Where(x => !a52Exclude.Contains(x.A.A52));
q = q
.OrderBy(x => x.A.A11)
.OrderBy(x => x.D.D11);
totalCount = q.Count();
return q.Take(Parameters.ROW_LIMIT).Select(j => new QueryRow
{
A01 = j.A.A01,
A01a = j.A.A01a,
A01b = j.A.A01b,
A02 = j.A.A02,
A03 = j.A.A03,
A11 = j.A.A11,
A12 = j.A.A12,
A12a = j.A.A12a,
A12b = j.A.A12b,
A12c = j.A.A12c,
....... redacted for brevity
D43 = j.D.D43,
D44 = j.D.D44,
D45 = j.D.D45,
Z1 = j.D.Z1
}).ToList();
}
(x)=>
new string[] { "0", "1", String.Empty }.Contains(x.A.A42) &&
inner.Contains(x.D.D21) &&
(x.D.D11 != null && x.D.D11 != String.Empty) &&
new string[] { "1", "2" }.Contains(x.D.D45) &&
(
(x.D.D18.CompareTo("19000101") >= 0 && x.D.D18.CompareTo(x.A.A21) <= 0) && //D18 >= '1900101' AND D18 <= A21
(x.D.D43.CompareTo("19000101") >= 0 && x.D.D43.CompareTo(x.D.D18) >= 0) // D43 >= '19000101'
) &&
x.D.D43.CompareTo("20050623") < 0