人总应该前进的,也应该一直保持学习的态度,最近在做个小项目的时候就开始全面抛弃了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条件限制,之前我就在这别了好长时间,气啊!j_0004.gifj_0004.gifj_0004.gif

(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觉得有意思的问题,记忆比较清晰的就是这几种情况了,在之后的开发学习过程中遇到问题还会与大家一些分享。