回答

收藏

将Linq表达式转换为SQL Server查询

技术问答 技术问答 231 人阅读 | 0 人回复 | 2023-09-13

我正在使用某些crm框架,并且此框架没有任何内部orm,并且未使用实体框架,仅使用普通sql查询。
# ?2 ~1 E+ d: L( D* ^我在数据库中的每个表都有实体。所以我有例如:
0 e. o- _; e/ H7 F" k9 Fpublic class Customer{/ U1 p7 M% U$ m3 c, L% N8 t8 _
    public string FirstName{get;set;}: n* t( s0 h& l% U
    public int Status{get;set;}
% Z2 c: ?4 w$ B9 E, m}
2 _' ]2 T1 \1 ^( P2 r" @无论如何,我可以编写linq查询并将其转换为sql, 而无需使用实体框架或NHibernate ?我正在寻找类似的东西。( u( @6 A8 _0 D$ e7 I6 X) i
IQueryable linq = from LinqProvider.Get() int customer where customer.FirstName == "test" and Status > 1;
# j' g6 V5 h7 M. j6 j' |string sqlQuery = LinqProvider.ToSqlQuery(linq);
, d- A, c8 C9 J0 _& I" V+ v6 ^9 s# D//Select * from Customer where FirstName = "test" and Status > 1$ m3 {" i9 Q' W2 r) A( W9 f, ]
我将拥有一些高级功能,例如Join排序和聚合功能。
2 o- }: n$ j1 v* @               
% b& \* v& Q% c& Z3 F解决方案:, }0 Z, v! Q0 m2 b4 R. N5 o* R
               
* \: l: E( j* q* I' C: y
* c0 G8 W  D+ I4 a7 n
9 H% a# A; N& \) r# T0 ~4 ~                请注意以下两行之间的差异(lambda形式的linq):
  u, G& q- q2 w1 Y6 Dvar dataQ = Customer.Where(o=>(o.FirstName == "test" && o.Status > 1);; c1 H% V% x- N$ t  @
var dataL = Customer.Where(o=>(o.FirstName == "test" && o.Status > 1).ToList();2 o# G+ ]0 ^$ g+ U" o
var dataS = Customer.SingleOrDefault(o=>(o.FirstName == "test" && o.Status > 1);
, ^/ s. ]( u) J据我所知,linq查询被转换为lamba,然后进行了优化和自动编译(来自框架4.5)。默认情况下,数据库上下文应启用延迟加载和开放式并发。延迟加载意味着在实际需要之前不会获取数据。在这种情况下.ToList(),SingleOrDefault将强制重试数据。这意味着它们将显示在Entity. Y3 h# ^  z4 {! w, o' |
Framework Profiler中。9 `. u# N. H; X$ `# f: u# P
如果您不想使用它,或者可以不使用它,则可以使用ToToTraceString麓,但是它不能继续工作,dataL或者dataS因为它们不是查询,而是具体实例。
: o" m# p4 J0 |6 d4 ]File.AppendAllText(traceFile, ((ObjectQuery)dataQ).ToTraceString());   ; S$ E: k/ Y0 y9 j
return dataQ.ToList();
! i5 _( a, ~6 {; S% E! [编辑
( h- ~1 x- ~$ m/ c  _- v$ j4 @我所做的假设:- t1 q& i- V4 D9 p9 Q
我的假设是您不能编写正确的SQL,但是对Linq有点熟悉。
, f3 ]) H8 }$ v4 {# Q; U( @您有不常用的数据库,该数据库将使用第三方提供程序,或者甚至无法执行此操作。
+ ^  x. U( W" X; w3 I& n3 P0 N" z您(手动?)为数据库表创建了映射5 E' b) \# r8 A6 g+ ?4 N

7 }; H& w* q0 @5 P% g8 P! q现在,您可以做的是使用 代码优先 方法。您从这些类生成数据库。然后,您对其进行查询并获得了 SQL4 ]% s: o# _! J6 s
。我以为这很清楚。请注意,您可能还希望获得代码优先迁移,因为您最有可能需要进行更改。
, R; S: g/ d: Q0 i, p编辑2
: Y9 C0 x: V; t- v" g3 X4 ], p举个例子:https :( X+ X5 L- J" Q: D/ O! b; M
//gist.github.com/margusmartsepp/f9fcc9178600ca53acf6+ ]4 q( |8 X8 q+ O1 p0 q, N, q0 A
    [Table("CustomerTest")]
! [6 k1 S- v2 ]% S2 p    public class Customer
( f' ]0 r% Y$ d    {
( B' O2 r6 D5 o& D+ S  Z' K0 c. ]        [Key]5 h4 s" |$ T0 @7 x/ p- `% L1 M: I3 r; x4 G
        public int Id { get; set; }
; t5 H( q3 w& ^; ^4 p        public string FirstName { get; set; }
* @0 X% |2 E( \0 B% Y! @* _        public int Status { get; set; }
7 a1 m- Q$ R+ V$ F$ ^+ m* a    }& l& w( W; s' A& ~; q
    public class CustomerContext : DbContext
! S# O1 \$ [* l- o2 I    {
( r1 M/ r1 s5 e- ^! [8 Z        public CustomerContext(): base("name=Program.CustomerContext"){}! b: U. C4 @* {2 ~+ L( p* N
        public DbSet Customers { get; set; }8 _7 N. \" N5 R3 W
    }7 i  {- |6 d9 q% t
    //PM> Install-Package EntityFramework
: s1 d2 p% U, e/ ~; K    //PM> Install-Package EntityFramework.SqlServerCompact5 |% M7 q5 p% ]( I  {
    static void Main(string[] args)7 C3 \% j, o2 `7 m8 F: z
    {
; |( v& m$ v8 J1 ]9 \( P, ~        using (var db = new CustomerContext())$ y) }2 k5 o" l6 |* ]5 t
        {
# S" {7 @! C- n! i! D  R            var item = new Customer {FirstName = "test", Status = 2};
: s0 m! m; n8 K0 r3 E& @" P            db.Customers.Add(item);
0 ?' F9 K1 ^. H/ f0 r3 b( Z            db.SaveChanges();
1 p2 \1 R' h$ t6 v0 {* E3 b0 t            var items = db.Customers.Where(o => (o.FirstName == "test" && o.Status > 1));. D+ u6 w5 `0 p6 @1 f% m* |
            Console.WriteLine(items.ToString());
8 V5 Q" U; ~) Q( B. v        }
, \" ~( C" J6 C- t* V/ n        Console.ReadKey();
- w5 g3 I$ e6 l9 }8 d    }$ T  e# m& P  F6 ?
输出示例:7 Y7 @1 a2 W& G: I" ^6 o. b
SELECT
- b$ m3 k3 R! R6 N    [Extent1].[Id] AS [Id],
! d4 a: j  G+ b$ F    [Extent1].[FirstName] AS [FirstName],
" }! v( ]/ D- _, k! p5 S    [Extent1].[Status] AS [Status]
& t* l% q4 Y2 H/ U0 e    FROM [CustomerTest] AS [Extent1]' f7 l6 p7 Y* @  D
    WHERE (N'test' = [Extent1].[FirstName]) AND ([Extent1].[Status] > 1)
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则