linq入门杂荟

查询表达式(LINQ)简介

LINQ是Language Integrated Query的简称,它是集成在.NET编程语言中的一种特性。已成为编程语言的一个组成部分,在编写程序时可以得到很好的编译时语法检查,丰富的元数据,智能感知、静态类型等强类型语言的好处。并且它同时还使得查询可以方便地对内存中的信息进行查询而不仅仅只是外部数据源。

LINQ定义了一组标准查询操作符用于在所有基于.NET平台的编程语言中更加直接地声明跨越、过滤和投射操作的统一方式,标准查询操作符允许查询作用于所有基于IEnumerable<T>接口的源,并且它还允许适合于目标域或技术的第三方特定域操作符来扩大标准查询操作符集,更重要的是,第三方操作符可以用它们自己的提供附加服务的实现来自由地替换标准查询操作符,根据LINQ模式的习俗,这些查询喜欢采用与标准查询操作符相同的语言集成和工具支持。

我们来总体看看LINQ架构

LINQ架构

LINQ包括五个部分:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。

LINQ to SQL全称基于关系数据的.NET语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能。其建立于公共语言类型系统中的基于SQL的模式定义的集成之上,当保持关系型模型表达能力和对底层存储的直接查询评测的性能时,这个集成在关系型数据之上提供强类型。

LINQ to XML在System.Xml.LINQ命名空间下实现对XML的操作。采用高效、易用、内存中的XML工具在宿主编程语言中提供XPath/XQuery功能等。

说了这么多,我们还是用一个简单的实例说明一下微软LINQ to SQL框架为我们带来的体验。

LINQ to SQL实例

第一步:建立dbml(Database Mark Language。数据库描述语言,是一种xml格式的文档,用来描述数据库)文件,以Northwind数据库为例,上述Customers类被映射成一个表,对应数据库中的 Customers表

第二步:创建一个ASP.NET页面,在页面上加入一个GridView控件

第三步:编写代码进行数据绑定

第三步:编写后台绑定代码

第四步:运行显示结果。

第四步:显示

好了,就说这么多吧,大家应该对LINQ有了总体的了解

-----------datatable,dataset to linq------------

.net推出LINQ后就可以用这种更简洁易懂的类SQL语法的LINQ To DataTable 来解决以上问题。下面我例出几个示例分享。

using System.Linq;
using System.Text;
using System.Data;

1.基本方法:

 DataSet ds = new DataSet();
adapter.Fill(ds, "Customers");//读数据库略

var result = from s1 in ds.Tables["Customers"].AsEnumerable()

where s1.Field<string>("Region") == "SP" //转换成string后进行对比,如果为DBNull 则传回空字符串
select s1;

foreach (var item in result)
Console.WriteLine(item["CustomerID"]);
Console.ReadLine();

2.指定DataRowVersion:

var result = from s1 in ds.Tables["Customers"].AsEnumerable()
where !s1.IsNull("Region") && (string)s1["Region"] == "SP"
select s1;

3. Join组合查询:

var result = from s1 in ds.Tables["Customers"].AsEnumerable()
join s2 in ds.Tables["Orders"].AsEnumerable() on
s1.Field <string>("CustomerID") equals s2.Field<string>("CustomerID")
where s2.Field <DateTime>("OrderDate") > DateTime.Parse("1997/1/1") &&
s2.Field <DateTime>("OrderDate") < DateTime.Parse("1997/5/31")
select new
{
OrderID = s2.Field <int>("OrderID"),
CustomerName = s1.Field <string>("CompanyName"),
OrderDate = s2.Field <DateTime>("OrderDate")
};

4.Group

var result = from s in ds.Tables["Orders"].AsEnumerable()
group s by s.Field<string>("CustomerID") into g
select new
{
OrderID = g.First().Field <int>("OrderID"),
CustomerID = g.Key
};


5.返回前10行数据

var table = (from s1 in ds.Tables["Customers"].AsEnumerable() select s1).Take(10);

-----数据操作部分------

DataClassesDataContext db = new DataClassesDataContext();
//取所有数据
public IQueryable<UserInfo> GetAllUser()
{
return db.UserInfo;
}
//分页原理
public IQueryable PageUser(int skip,int topnum)
{
return GetAllUser().Skip(skip).Take(topnum);
}
//获取单个实体
public UserInfo GetUserinfo(int userid)
{
return db.UserInfo.SingleOrDefault(d => d.UserID == userid);
}
//添加
public void Add(UserInfo model)
{
db.UserInfo.InsertOnSubmit(model);
}
//修改
public void Update(UserInfo model)
{
var user = GetUserinfo(model.UserID);
user = model;
Save();
}
//删除
public void Delete(UserInfo model)
{
db.UserInfo.DeleteOnSubmit(model);
}
public void Save()
{
db.SubmitChanges();
}
----------linq 使用存储过程-----------
1 首先从服务器资源管理器中把存储过程拖到linq to sql的类设计器中,在该类中会自动生成一个方法如:
[Function(Name="dbo.User_Login")]
public int User_Login([Parameter(Name="Username", DbType="NVarChar(50)")] string username, [Parameter(Name="Password", DbType="VarBinary(1)")] System.Data.Linq.Binary password, [Parameter(Name="IP", DbType="NVarChar(50)")] string iP, [Parameter(DbType="Int")] ref System.Nullable<int> con)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), username, password, iP, con);
con = ((System.Nullable<int>)(result.GetParameterValue(3)));
return ((int)(result.ReturnValue));
}
外部可如此调用
public int Userlogin(string username,System.Data.Linq.Binary pwd,string ip,ref int? con)
{
return db.User_Login(username,pwd,ip,ref con);
}

有时候会到这种需求,存储过程返回多个结果集合,那么这时候怎么操作才能把结果集分开呢。比如下面这个存储过程,能不能把Customer和Order的结果集分别取到呢?

create procedure dbo.linqDemo5  as      
select * from customers
select * from orders

通过设计器来映射存储过程,不能识别多个结果集。如果自动创建结果类的话,它只识别出第一个返回的结果集,比如上面这个存储过程,自动生成的结果类

linqDemo5Result里面只包括customer表的所有字段。不过,Linq to SQL中提供了ResultType Attribute来标志该存储过程会返回什么类型的对象以及IMultipleResults接口来满足获得多个结果集的问题。首先看看自动生成的方法:

 [Function(Name="dbo.linqDemo5")]   
public ISingleResult<linqDemo5Result> linqDemo5()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))); return ((ISingleResult<linqDemo5Result>)(result.ReturnValue));
}

我们对它进行修改,用ResultType标记返回的结果中将包含哪些类型,再使用IMultipleResults返回多个结果集

[Function(Name="dbo.linqDemo5")]   
[ResultType(typeof(Customer))]
[ResultType(typeof(Order))]
public IMultipleResults linqDemo5()
{
return (IMultipleResults)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())))).ReturnValue;
}

在我们的代码中如下使用:

NorthwindDataContext ctx = new NorthwindDataContext();   
IMultipleResults results = ctx.linqDemo5();
foreach (var c in results.GetResult<Customer>())
{ Console.WriteLine(c); }
foreach (var o in results.GetResult<Order>())
{ Console.WriteLine(o); }

值得注意的是GetResult的顺序依赖于存储过程中返回结果的顺序,如果先返回customer结果集就必须先调用GetResult<Customer>,否则会出现异常。可以说在调用GetResult的时候,根据对象属性映射列来取值,一旦发现不匹配就会出现错误。假设里面使用的dataReader,构造Customer对象的时候对属性进行赋值,c.CustomerID=reader["CustomerID"],如果没有这一列就抛出异常了。所以说在存储过程中使用多个结果集限制性非常大

可参考: http://www.yaosansi.com/post/1188.html
---------------------

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值