如何随机读取数据,如何随机排序?
在“SQL时代”我们随机读取一条记录的方法是
当时在LINQ中怎么做?我曾经想当然的用下面的语句,期待他能返回正确的结果
但实际上,LINQ无情地把我那句orderby给过滤掉了,怎么办?难道又要写SQL语句来实现?
假如ORDERBY只是查询条件中的一小部分呢?所有的东西都写成SQL语句?不用!这里有一个小技巧:
如何执行IN操作
在BETA2中,Linq加入了对IN操作的支持,使用起来很简单,把Contains反过来用就可以了
LINQ会自动帮你生成类似下面的语句
如何执行LIKE操作
LIKE也是用Contains来实现,只不过需我们手动用循环组合一下,并且……
LINQ会自动帮你生成类似下面的语句
等一下?为什么两个都是bbb?aaa哪儿去了?这是个BUG么?不是!
这是LINQ的运行机制造成的,由于LINQ在最终使用数据之前并不生成SQL语句,只是进行查询条件的组合。由于keyWords以Enumerate的方式Pop出来,LINQ拿到的keyWord只是最后的值。
那我们该怎么办?很简单,一行代码搞定。
看起来很奇怪是吧?但恰恰就是这么一行看似多余的,一个思维正常的程序员平常绝对不会写的代码,起了重大作用。
如何返回业务实体到上层逻辑
几乎所有的Linq教程都是查询然后foreach,甚至可以select匿名类,这在演示中确实是很方便,很酷。但实际应用中,在多层结构流行的今天,谁又会真的这么用呢?我们需要把Linq产生的数据返回给上层,匿名类在这个地方(其他地方,比如逻辑层用来解决一些事情还是比较方便的)除了看起来比较酷以外还有什么其他意义?
LINQ会为我们的数据表、视图生成Table<T>,但实际应用中,我们会把在UI层引用LINQ所在的工程,然后直接使用这个Table<T>么?至少我不会
我们需要把Table转换成我们自己定义的实体(Entity/Model)
select new Entity { ... } 不就完了?没错,但是如果我有类似
GetUserById(Guid UserId)
GetAllUsers()
GetAllActiveUsers()
是不是要在所有方法中,把这个select写一遍?可不可以把这个select独立成一个方法?
像之前所说的,LINQ在最终使用数据之前并不生成SQL语句,也就是说在ToList(), Any(), foreach等等之前,你可以任意的组合,反复地查询,这就给我们独立select方法提供了可能。
同样的方法适用于分页等一些会在多出使用的操作。
在“SQL时代”我们随机读取一条记录的方法是
1SELECT TOP 1 * FROM TABLE1 ORDER BY NEWID()
当时在LINQ中怎么做?我曾经想当然的用下面的语句,期待他能返回正确的结果
1var customer = (from c in ctx.Customers orderby Guid.NewGuid()).First();
但实际上,LINQ无情地把我那句orderby给过滤掉了,怎么办?难道又要写SQL语句来实现?
假如ORDERBY只是查询条件中的一小部分呢?所有的东西都写成SQL语句?不用!这里有一个小技巧:
1//在自动生成的mapping code中添加
2[Function(Name = "NEWID", IsComposable = true)]
3public Guid NEWID()
4{
5 return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
6}
7
8//在使用中
9var customer = (from c in ctx.Customers orderby ctx.NEWID()).First();
2[Function(Name = "NEWID", IsComposable = true)]
3public Guid NEWID()
4{
5 return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
6}
7
8//在使用中
9var customer = (from c in ctx.Customers orderby ctx.NEWID()).First();
如何执行IN操作
在BETA2中,Linq加入了对IN操作的支持,使用起来很简单,把Contains反过来用就可以了
1 string[] tags = new string[] { "aaa", "bbb" };
2 var result = from p in ctx.Posts
3 join t in ctx.Tags on p.PostId equals t.PostId
4 where tags.Contains(t.Text)
5 select p;
2 var result = from p in ctx.Posts
3 join t in ctx.Tags on p.PostId equals t.PostId
4 where tags.Contains(t.Text)
5 select p;
LINQ会自动帮你生成类似下面的语句
1Text IN ('aaa', 'bbb')
如何执行LIKE操作
LIKE也是用Contains来实现,只不过需我们手动用循环组合一下,并且……
1 string[] keyWords = new string[] { "aaa", "bbb" };
2 var result = from p in ctx.Posts
3 select p;
4
5 foreach(string keyWord in keyWords)
6 {
7 result = result.Where(p => p.Text.Contains(keyWord));
8 }
2 var result = from p in ctx.Posts
3 select p;
4
5 foreach(string keyWord in keyWords)
6 {
7 result = result.Where(p => p.Text.Contains(keyWord));
8 }
LINQ会自动帮你生成类似下面的语句
1Text LIKE @p0 AND Text LIKE @p1, @p0=N'%bbb%', @p1=N'%bbb%'
等一下?为什么两个都是bbb?aaa哪儿去了?这是个BUG么?不是!
这是LINQ的运行机制造成的,由于LINQ在最终使用数据之前并不生成SQL语句,只是进行查询条件的组合。由于keyWords以Enumerate的方式Pop出来,LINQ拿到的keyWord只是最后的值。
那我们该怎么办?很简单,一行代码搞定。
foreach(string keyWord in keyWords)
{
string key = keyWord;
result = result.Where(p => p.Text.Contains(key));
}
{
string key = keyWord;
result = result.Where(p => p.Text.Contains(key));
}
看起来很奇怪是吧?但恰恰就是这么一行看似多余的,一个思维正常的程序员平常绝对不会写的代码,起了重大作用。
如何返回业务实体到上层逻辑
几乎所有的Linq教程都是查询然后foreach,甚至可以select匿名类,这在演示中确实是很方便,很酷。但实际应用中,在多层结构流行的今天,谁又会真的这么用呢?我们需要把Linq产生的数据返回给上层,匿名类在这个地方(其他地方,比如逻辑层用来解决一些事情还是比较方便的)除了看起来比较酷以外还有什么其他意义?
LINQ会为我们的数据表、视图生成Table<T>,但实际应用中,我们会把在UI层引用LINQ所在的工程,然后直接使用这个Table<T>么?至少我不会
我们需要把Table转换成我们自己定义的实体(Entity/Model)
select new Entity { ... } 不就完了?没错,但是如果我有类似
GetUserById(Guid UserId)
GetAllUsers()
GetAllActiveUsers()
是不是要在所有方法中,把这个select写一遍?可不可以把这个select独立成一个方法?
像之前所说的,LINQ在最终使用数据之前并不生成SQL语句,也就是说在ToList(), Any(), foreach等等之前,你可以任意的组合,反复地查询,这就给我们独立select方法提供了可能。
1private IQueryable<Entities.Tag> TranslateToEntity(IQueryable<Tag> tags)
2{
3 return from t in tags
4 select new Entities.Tag
5 {
6 TagId = t.TagId,
7 Text = t.Text,
8 CreateTime = t.CreateTime
9 };
10}
2{
3 return from t in tags
4 select new Entities.Tag
5 {
6 TagId = t.TagId,
7 Text = t.Text,
8 CreateTime = t.CreateTime
9 };
10}
1List<Entity.Tag> GetAllUsers()
2{
3 //var users =
4 return TranslateToEntity(users).ToList();
5}
2{
3 //var users =
4 return TranslateToEntity(users).ToList();
5}
同样的方法适用于分页等一些会在多出使用的操作。