惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
S
Schneier on Security
T
Threat Research - Cisco Blogs
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Hacker News
The Hacker News
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
T
Tenable Blog
S
Secure Thoughts
T
Threatpost
V2EX - 技术
V2EX - 技术
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
小众软件
小众软件
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Y
Y Combinator Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
P
Privacy International News Feed
H
Heimdal Security Blog
量子位
B
Blog

博客园 - 海南K.K

海南海口滨海大道洛杉矶城一线海景公寓出售(09年建成,面积88~126平米共六套,一次性团购可打折) 出售海南海口南渡江畔私家别墅(楼高4层,占地388平米,建筑面积570平米) 代友发布:海南海口海景豪宅转让(16层5室3厅3卫2阳台288.0m²) 百度谈人生?别再往自己脸上贴金了! douban api,你到底想做什么? Javascript: 从最受误解的语言,到最流行的语言 LINQ那些事(9)-解析Table<T>.Attach引发的异常和解决方法 你可能不熟悉的CSS 三言二拍:海南的软件业 海口房事:海口纵贯线(-海南购房-海口购房-海南二手房-海口二手房-海南国际旅游岛-养老-过冬-) 海口房事:看京城人争当海南岛民 (-海南购房-海口购房-海南二手房-海口二手房-过冬-养老-国际旅游岛-) 海南海口生态公园公寓出售-海南购房-海口购房-海南二手房-海口二手房-过冬-养老-国际旅游岛- Code4Fun: 通过XML模板系统实现对象的灵活序列化 LINQ那些事儿(4)- Query Expression和Query Operator LINQ那些事儿(3)- 事务和并发冲突处理 LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作 LINQ那些事儿(1)- 定义从关系数据库到entity class的映射 LINQ那些事 LINQ那些事儿(6)-对象生命周期管理
LINQ那些事儿(5)- 动态查询
海南K.K · 2010-01-01 · via 博客园 - 海南K.K

本文讨论了在LINQ2SQL中执行动态查询的方法

所谓动态查询,是指查询条件或查询值都是在运行时才能确定的查询。这就意味着我们不能hard-code定义查询变量(query variable),只有根据查询时传递的条件来拼凑。下面我们看看几组不同条件组合的查询。

1) 用户输入查询条件:City为”London”且ContactName包含”Thomas”

public IQueryable<Customer> GetCustomers(string city, string contactName)
{
	var context = GenerateContext();
	IQueryable<Customer> result = context.Customers;

	if (!string.IsNullOrEmpty(city))
	{
		result = result.Where(c => c.City == city);
	}

	if (!string.IsNullOrEmpty(contactName))
	{
		result = result.Where(c => c.ContactName.Contains(contactName));
	}

	return result;
}

2) 用户输入查询条件:City为”London”或”Paris”

由于Where和Where的连接是表示AND的关系,所以我们无法用1)的方法来表达这个查询。有一个可以利用的query operator是Union:

var context = GenerateContext();
IQueryable<Customer> result = null;
string[] cities = { "London", "Paris" };

foreach (string item in cities)
{
    string tmp = item;
    result = result == null ?
    context.Customers.Where(c => c.City == tmp) :
    result.Union(context.Customers.Where(c => c.City == tmp));
}

context.Log = Console.Out;
Console.WriteLine(result.Count());

虽然结果符合我们的要求,但是通过输出的SQL语句,你可以看到对于这种方式构造的Expression Tree,SQL并没有我们想要的精简(我们期望的是t0.City=’London’ OR t0.City=’Paris’)。输出SQL如下:

SELECT COUNT(*) AS [value]
FROM (
    SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[Cont
actTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[
Country], [t0].[Phone], [t0].[Fax]
    FROM [dbo].[Customers] AS [t0]
    WHERE [t0].[City] = @p0
    UNION
    SELECT [t1].[CustomerID], [t1].[CompanyName], [t1].[ContactName], [t1].[Cont
actTitle], [t1].[Address], [t1].[City], [t1].[Region], [t1].[PostalCode], [t1].[
Country], [t1].[Phone], [t1].[Fax]
    FROM [dbo].[Customers] AS [t1]
    WHERE [t1].[City] = @p1
    ) AS [t2]

另外的方法就是是根据所有查询条件和查询值,给Where构造一个Expession。首先来看看Where的签名:

IQueryable<T> Where<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)

对于这样一个Expression,如果你熟悉Expression Tree的构造方法,完全可以自己写。《C# 3.0 In Nutshell》的作者写了一个小巧的PrediateBuilder,可以帮助我们用lambda expression快速构造这样的expression:

var context = GenerateContext();
Expression<Func<Customer, bool>> filter = PredicateBuilder.False<Customer>();
string[] cities = { "London", "Paris" };

foreach (string item in cities)
{
    string tmp = item;
    filter = filter.Or(c => c.City == tmp);
}

context.Log = Console.Out;
context.Customers.Where(filter).Count().Dump();

输出的SQL也是我们期待的结果

SELECT COUNT(*) AS [value]
FROM [dbo].[Customers] AS [t0]
WHERE ([t0].[City] = @p0) OR ([t0].[City] = @p1)

最后,如果你对以前拼接SQL语句的方式还是念念不忘的话,可以去用Dynamic LINQ,参考SocttGu’s Blog

参考资料:

PredicateBuilder http://www.albahari.com/nutshell/predicatebuilder.aspx

Dynamic LINQ  http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

链接

1、 LINQ那些事儿(1)- 定义从关系数据库到Entity Class的映射

2、 LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作

3、 LINQ那些事儿(3)- 事务和并发冲突处理

4、 LINQ那些事儿(4)- Query Expression和Query Operator

5、 LINQ那些事儿(5)- 动态查询

6、 LINQ那些事儿(6)- DataContext的对象生命周期管理

7、 LINQ那些事儿(7)- 通过自定义IEnumerable<T>来扩展LINQ

8、LINQ那些事儿(8)- 通过自定义IQueryable<T>和IQueryableProvider来扩展LINQ