人总应该前进的,也应该一直保持学习的态度,最近在做个小项目的时候就开始全面抛弃了ADO.NET和SQLHelper,开始使用了Linq to Sql。
有时候人就要逼一逼自己,要不总是下不了狠心,当然学习的过程很苦涩,但是坚持下去就会有修成正果的一天。
今天想与大家分享一下最近在Linq上遇到问题的解决方法,没有什么大难点,就是自己了解到的一些东西,可能在书上很难有体现,这东西还是实战遇到的情况会更多一些,五花八门的问题也挺多。
我用的环境是Visual Studio 2010,.Net Framework 4.0。
1、遇到多个条件句的时候要如何去写
通常遇到多个条件句与SQL的写法几乎没多大区别,比如
var result = from s in context.UserInfo where s.user_account == account && s.user_account != null && s.user_isdelete == false && !s.user_id.Equals(id) select context.UserInfo;
account和id是已知的,通过几个条件
(1)user_account == account
(2)user_acount字段 不能为空
(3)user_isdelete用户未被删除
(4)排除uesr_id为id的这个用户
将结果筛选出来。
对应的SQL语句当然是
select * from [userinfo] where user_account = account and user_account is not null and !user_isdelete and user_id <> idli
注意的是SQL下的and , or 符号在Linq下为&& ,||,其实大家就别把他当SQL写就好,就是C#语法就行,刚开始可能需要适应。
2、升级版,针对不同的情况,条件不同,其他都相同的Linq语句要怎么写
这条是稍微有点意思的,就是指如果筛选条件不同的时候,我们的where中的条件句也是不一样的,这时候就是利用if else去区分,然后组成不同的SQL语句,查询最后的结果集。
在SQL中我们可以用字符串去拼,最后通过字符串连接组成最后的SQL语句。比如有多个角色,上级只能看直属下级的信息,。
void ViewInfo(string role) { string selectCmd = "select * from userinfo "; if(role.Equal("军长")) { selectCmd += "where user_role='师长' "; } else if(role.Equal("师长")) { selectCmd += "where user_role='旅长' "; } else if(role.Equal("旅长")) { selectCmd += "where user_role='团长' "; } ..... selectCmd += "order by user_id desc"; ..... }
因为SQL是以字符串的形式出现的,所以我们可以像上面那样写,但是大家想想如果要是Linq怎么办呢?难道要根据不同条件把每个Linq语句写多次?答案是不需要,大家可以像这样写
void ViewInfo(string role) { var result = from s in context.userinfo orderby s.user_id descending select context.userinfo; if(role.Equal("军长")) { result = result.Where(p => p.user_role.Equal("师长")); } else if(role.Equal("师长")) { result = result.Where(p => p.user_role.Equal("旅长")); } else if(role.Equal("旅长")) { result = result.Where(p => p.user_role.Equal("团长")); } ..... ..... }
像这样使用.Where()函数时需要两点,
(1)调用完.Where()必须还得返回到之前的数据集result中去,否则相当于没有加这个where条件限制,之前我就在这别了好长时间,气啊!
(2)我们可以连续使用.Where(),像这样
if(role.Equal("军长")) { result = result.Where(p => p.user_role.Equal("师长")).Where(p => p.user_age < 50); }
但大家要注意的是这条语句翻译过来是“角色为师长和年龄小于50”。是的,两个.Where()表示的是这两个条件是以 and 的方式存在,如果想表示或的话,就需要在一个.Where()中用||去表示。
3、针对插入int型自增长字段,Linq下要怎么写
这个问题我遇到的原因是忘记把主键ID设置成自增长类型,然后在调用.InsertOnSubmit()的时候就会报错了,这块大家只要注意建表时把主键设置成自增长类型就好了。否则报错出现黄页的时候,每次都会停在.SubmitChanges()函数处。
4、针对SQL 中where XXX in (子查询) 等价Linq如何写
还是用例子来给大家讲
var list = from c in context.UserInfo where (from s in context.Role where s.role_name.StartsWith("B") || s.Role_Name.Equals("Admin") select new { RoleId = s.role_id }.RoleId).Contains(c.user_roleid) select new { Id = c.user_id, Name = c.user_name };
大家主要是看子查询,描述的是父查询的c.user_roleid要包含在一个范围里,而这个范围就是,role_name的首字符为B或者role_name为Admin对应的role_id了。大家看到Contains可能都会想到是string类型的,类SQL like的查询,但是C#可以把它换成泛型那种使用,所以就方便好多啦。
5、关于.SubmitChanges()方法
这块是想提一下,就是如果你在执行多条对数据进行操作的语句时,比如你进行了几条数据的添加,又删除了几条数据,又修改了几条数据,OK,如果这些动作都是在一个操作里(我是指你点击一下某个按钮,然后就执行这些操作的话),那么你只要在最后写一次.SubmitChanges()的执行就可以了。
形象点就是
//插入数据 XXX.InsertOnSubmit(SingleXXX1); XXX.InsertOnSubmit(SingleXXX2); XXX.InsertOnSubmit(SingleXXX3); //删除数据 XXX.DeleteOnSubmit(SingleXXX4); XXX.DeleteOnSubmit(SingleXXX5); XXX.DeleteOnSubmit(SingleXXX6); //最后写一遍 XXX.SubmitChanges();
而且还要说明一点的是,如果你的context中包含的是多个表,也可以对不同的表进行不同的操作之后,写一遍.SubmitChanges()就行,大家灵活使用就好。
6、针对SQL 中where XXX == (子查询)的结果 等价Linq如何写
举个例子(也许不用说明大家也都能看明白了):
var result = from s in context.Role where role_name== (from p in context.UserInfo where p.Id.Equals(id) select new { RoleName = p.RoleName}).First().RoleName select new { RoleId = s.RoleId};
说明一下:我已知一个值id,要做的是去查找userinfo表中这个id对应的role_id,然后根据这个role_id在role表中查找出对应的rolename。
SQL原型很简单:
select [role_name] from [Role] where [role_id] == (select [role_id] from [UserInfo] where user_id = id);
再看Linq语句,因为id为主键,所以查出的结果集.First()第一条就是唯一一条结果,这条结果的RoleName属性就可以用.RoleName去获得。这是一个很简单的例子,不过就算遇到复杂的,大家只要条理清晰一些都不是什么问题。
以上是最近遇到的一些Linq觉得有意思的问题,记忆比较清晰的就是这几种情况了,在之后的开发学习过程中遇到问题还会与大家一些分享。