linq to sql常用方法总结
Linq To Sql常用方法使用总结
准备工作:
数据表:
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中所有的集合
1.1 用了匿名类的方法。
如果需要返回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。
1.2 指明实体的方法。
var s = from t1 in dc.Table1
select new tbMode
{
myID= t1.ID,
myCol= t1.Col1
};
2. 带条件查询
2.1 普通查询
例一:
查询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 tem = (from e in db.CustomerOrders
where e.WebsiteId == wareId
&& (dateFrom != null ? e.OrderAuditOn >= dateFrom : true)
&& (dateTo != null ? e.OrderAuditOn < dateTo : true)
&& (string.IsNullOrEmpty(OrderNo)?true:e.OrderNo == OrderNo)
&& e.OrderAuditOn.HasValue
select e).ToList();
列三:用indexOf模糊查询(注:三元运算符一定要打上括号)
var query = from sc in db.ShareData
where(string.IsNullOrEmpty(share_name) ? true : sc.ShareName.IndexOf(share_name)!=-1)
&& (string.IsNullOrEmpty(market_code) ? true : sc.MarketCode.IndexOf(market_code)!=-1)
select new ShareDataInfo
{
ShareCode = sc.ShareCode,
ShareName = sc.ShareName,
MarketCode = sc.MarketCode,
MarketName = sc.MarketName,
IsblackList = sc.IsBlackList
};
2.2 模糊查询
DBContext dc = new DBContext();
var s = from t1 in dc.Table1
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 t1 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 tb1 in dc.Table1
select tb1;
var q = from tb2 in dc.Table2
join tb1 in s1 //这里是将查询的数据 s1 再进行查询
on tb1.oID equals tb2.ID
select ……
9. 外部数据作中条件检索
int[] col2List = new int[5] {1,2,3,4,5};
DBContent dc = new DBContent();
var s1 = from tb1 in dc.Table1.Where(u=>col2List.Contains(u.Col2)) //查询列Col2的值包含在col2List中的数据(和 in 语法差不多)
select t1;
10. 查询出多条数据放入指定的Response.Mylist中。(list<> 的写法)
List<T_Sha_HSSharesCommissions> shareCom = db.T_Sha_HSSharesCommissions.Where(o => o.CommissionStatusID == (byte)Lcp.Api.Enums.CommissionStatus.已成 && o.CreatedOn >= beginDate && o.CreatedOn <= endDate).ToList();
shareCom.ForEach(o =>
{
sharecomlist = new HSSharesCommissionInfo();
sharecomlist.FinancingID = o.FinancingID;
sharecomlist.ShareCode = o.ShareCode;
sharecomlist.MarketCode = o.MarketCode;
sharecomlist.UserID = o.UserID;
sharecomlist.AccountCommissionID = o.AccountCommissionID;
req.HSSharesCommisionList.Add(sharecomlist);
});
11.linq to Entitle 时间差函数
列子:查出25天前创建时间的账号。
List<MallAgentAccount> accountToken = query.Where(o => System.Data.Objects.EntityFunctions.DiffDays(o.CreatedOn, DateTime.Now) >= 25).ToList();