注册 登录
编程论坛 F#论坛

Linq To Sql常用方法使用总结

bygg 发布于 2009-09-18 10:16, 11007 次点击
准备工作:
数据表:
Table1
ID        int        PK
Col1        varchar(50)
Col2        int
======================================
Table2
ID        int        PK
oID        int        FK
Remarks        varchar(50)
======================================
方法简介:
1.    查询
DBContext dc = new DBContext();              //实例化Linq To SQL 类
var s = from t1 in dc.Table1
    select t1;
s就是表Table1中所有的集合

如果需要返回Table1中的某几列。
var s = from t1 in dc.Table1
    select new
    {
        t1.ID,
        t1.Col1
};
        这样就只返回ID列和Col1列。
   
    如果要给返回的列指定别名,写法如下:
    var s = from t1 in dc.Table1
    select new
    {
        myID = t1.ID,
        myCol1 = t1.Col1
};
    这就相当于SQL语句中的 select ID as ‘myID’, Col1 as ‘myCol1’ from Table1。

2.    带条件查询
查询Table1中Col1列的值等于 ABC的所有记录
DBContext dc = new DBContext();
var s = from t1 in dc.Table1
    where t1.Col1==”ABC”     //或者 where t1.Col1.Equals(“ABC”);模糊查询用where t1.Col1. Contains (“ABC”) 相当于SQL语句中的 like ‘%ABC%’
    select t1;

还有一种更简单的方法

var s = dc.Table1.Where(u=>u.Col1.Equals(“ABC”));

在vs2008中,已经将所有容器(数组)都封闭了如上方法。类似的还有
 
var s = dc.Table1.First()    //取第一条数据
var s = dc.Table1.Last()     //取最后一条数据
但是这样写,必需注意异常处理。比如取第一条数据时,如果表Table1中根本就没有任何数据,则该语句会直接出错。
所以要么先判断表中的数据条数,要么加try…catch…进行处理。

3.    数据总数
DBContent dc = new DBContent();
var s = from t1 in dc.Table1
select new
{
    t1.ID     //为了速度更快点,所以只返回一列
};
    s.Count();    //这里就是数据总条数

    还有一种更简单的方法。
    int totailNo = dc.Table1.Count();    //这里的Count()里面同样可以加条件(u=>u.Col1.Equals(“ABC”))。

4.    两表联合查询(及左链接)
DBContent dc = new DBContent();
var s = from t1 in dc.Table1
    join t2 in dc.Table2
    on t1.ID equals t2.oID           //注:用了join ,on后面必需用 equals
    select new
    {
        T1.ID,
        T1.Col1,
        T2. Remarks
    };

左链接
var s = from t1 in dc.Table1
       join t2 in dc.Table2
    on t1. ID equals t2.oID into tempT
from t3 in tempT.DefaultIfEmpty()
select ……

Linq中的左连接(或右连接)就是使用DefaultIfEmpty()语法。但是使用DefaultIfEmpty()也需要用到into语法。如上例所示。在语句执行过后,t2是已经不存在了,因为它已经将数据转移到tempT中了;而tempT也不存在了,同样是因为通过DefaultIfEmpty()语法将数据转移到t3中了。

5.    Group by 语法
var result = from t in dc.Table1
         group t by t.ID into tempT     //这一步已经不存在 t 了 ,而 t 中的数据都到 tempT中了(数据是没移动的)
select new
{     
objID = tempT.Key,
                myCol2 = ts.Max(p => p. Col2)
};
在Linq 中,使用group by ,就必需使用into(也就是将group by 以后的数据放到一个新的容器中)。另外,值得注意的是,例子中的 objID= tempT.Key。这里也可以看出。是使用的tempT,而不是t,说明通过group by…into… 已经将查询出来的结果放进了tempT中。而tempT.Key就是 group by 后面的t.ID。

6.    分页
var s = from t1 in c.tbTests
    order by t1.ID     //分页都需要用到order by ,还将可能引起返回的数据不准确
     select new
    {
              myID = t1.ID,
              myCol1 = t1.Col1,
         };
    GridView1.DataSource = s.Skip(startRowIndex).Take(rowCount);
GridView1.DataBind();

startRowIndex:当前数据页数的第一条数据
rowCount:每页显示的数据条数

比如:
页数用 pageIndex表示。
当前是第一页,(pageIndex=0; startRowIndex=0)
每页显示20条数据,(rowCount=20)

那么我们显示下一页数据时,pageIndex=1;startRowIndex就应该是20(startRowIndex * RowCount)

7.    多条件动态查询
首先得写一个类(用于加载动态条件的)
    /// <summary>
    /// 生成多条件动态查询的条件结构 : AND用true ; OR用false
    /// </summary>
    public static class PredicateExtensions
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
        }
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.And(expr1.Body, invokedExpr), expr1.Parameters);
        }
}

上面这部分是一个老外写的,嘿嘿

下面进行动态查询
var searchPredicate1 = PredicateExtensions.True<Table1>();   
string col1 = textBox1.Text;
int col2 = int.Prase(textBox2.Text);
if (!string.IsNullOrEmpty(col1))
{
         searchPredicate1 = searchPredicate1.And(u => u.Col1.Contains(col1));   
}
if(col2 != 0)
{
    searchPredicate1 = searchPredicate1.And(u => u.Col2.Equals(col2));  
}
    DBContent dc = new DBContent();
    var s = from t1 in dc.Table1.Where(searchPredicate1)
        select t1;

8.    查询出来的数据再查询
DBContent dc = new DBContent();
var s1 = from t1 in dc.Table1
select t1;
    var q = from t1 in dc.Table2
        join t2 in s1          //这里是将查询的数据 s 再进行查询
        on t1.oID equals t2.ID
        select ……

9.    外部数据作中条件检索
int[] col2List = new int[5] {1,2,3,4,5};
DBContent dc = new DBContent();
var s1 = from t1 in dc.Table1.Where(u=>col2List.Contains(u.Col2))    //查询列Col2的值包含在col2List中的数据(和 in 语法差不多)
select t1;


[ 本帖最后由 bygg 于 2009-11-22 20:05 编辑 ]
15 回复
#2
xiaoguilin882009-09-26 11:50
学习,不错
#3
it0012009-10-12 13:14
很好,正在学。。
#4
台风海2009-11-22 01:06
这里涉及的仍然只是Linq to Sql,而非Linq。
#5
bygg2009-11-22 13:37
不知台风海,有什么好的资料或建议,还请发出来.呵呵
#6
台风海2009-11-22 16:35
实际上我是想说,楼主对Linq与Linq to SQL存在明显的概念上的混淆。
Linq to SQL 是隶属 Linq 家族中 for sql 的 provider。所以从楼主在本文中以及 https://bbs.bccn.net/thread-288231-1-1.html 所持的观点来看,不免会混淆视听。
有鉴于此,首先需要纠正的就是概念级的问题。
#7
bygg2009-11-22 20:05
你说得对,是我标题写错了.
#8
quanshui2009-12-18 13:01
学习,不错
#9
高阁逆风2010-01-08 11:53
mark
在研究lamda
#10
chenyiqing232010-02-06 23:47
新知识~~~新技术~~~
#11
lingsmile2010-04-09 18:47
学习学习,呵呵!
#12
vkwolf2010-08-15 18:11
好东西,谢谢LZ
#13
anhjisjllyq2011-05-19 12:39
#14
meixiafeng2011-05-31 16:23
不错 收藏了
#15
鸥翔鱼游2014-04-22 14:50
看了此贴菜鸟又涨姿势了
#16
saintok2017-10-17 20:28
谢谢楼主的分享~~~
1