linq入门杂荟

原创 2011年01月11日 13:33:00

查询表达式(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
---------------------

LINQ学习心得分享----(一)LINQ简介和基础学习

这一节主要向大家讲三个问题,第一个问题什么是LINQ,第二个问题LINQ主要解决什么问题,第三个问题学习LINQ需要做哪些基本的准备。      首先第一个问题,什么是LINQ?LINQ中文翻译为语...
  • xuemoyao
  • xuemoyao
  • 2012年10月08日 11:27
  • 2689

LINQ to SQL使用教程

LINQ to SQL使用教程 前些时间用LINQ to SQL做了一些项目,现在打算总结一下,帮助新手快速入门,并写一些别的教程没提到的东西。 一、LINQ to SQL和别的LINQ t...
  • moshansk
  • moshansk
  • 2017年09月04日 14:52
  • 383

ebs R12 杂收杂发 代码

DECLARE   l_iface_rec        mtl_transactions_interface%ROWTYPE;   l_iface_lot_rec    mtl_transactio...
  • lyyong2007
  • lyyong2007
  • 2015年11月23日 20:58
  • 314

工时估算

1.表设计(熟悉)2.原型转jsp3.页面添加脚本校验4.数据列表(共用)5.数据来源6.新增附件7.弹出页面选择数据8.增加修改9.数据显示10.下载附件11.其它。 ...
  • soft_xiaohui
  • soft_xiaohui
  • 2010年12月22日 17:05
  • 430

一分钟了解"用matlab计算信杂比SCR 以及 背景区域的标准差"

%求SCR和方差的方法 clear,clc,close all imgName=input('请输入bmp文件名,要有单引号,要有后缀:'); img=imread(imgName); fig...
  • yes1989yes
  • yes1989yes
  • 2017年08月11日 22:05
  • 202

C#基础之LINQ查询语句的简单使用(一)

l      对数组查询(排序,查找) l      对集合查询(排序,分组) l      多种条件综合使用的简单实例 在不触及数据库的前提下,从一些数据中查询出需要的数据,最简单方便的莫过于LIN...
  • u011593927
  • u011593927
  • 2013年11月07日 14:52
  • 3284

使用存储过程杂入杂出-出问题

原因: 问题:在后台使用存储过程往mtl_transaction_interface表中插入数据,因为改错了科目ID,最后导致生成总账日记帐的出错error10,公司间不平衡.   ...
  • more_mins
  • more_mins
  • 2014年09月09日 15:11
  • 297

linq学习 Linq to DataSet

Linq to DataSet Linq to  DataSet将Linq与ADO.NET集成,通过ADO.NET获取数据,然后通过Linq进行查询,从而实现对数据的复杂查询,Linq to...
  • Draling
  • Draling
  • 2012年04月22日 10:20
  • 2923

选择某种Map集合保存学号从1到15的学员的学号(键)和姓名(值)

/*选择某种Map集合保存学号从1到15的学员的学号(键)和姓名(值),  * 学号用字符串表示,输入的时候要以学号乱序的方式存入Map集合,  * 然后按照学号从大到小的顺序将Map集合中的元素...
  • scissorhandsl
  • scissorhandsl
  • 2017年11月26日 19:56
  • 95

Dapper.NET使用入门(一)【LINQ2Dapper】

此例子是使用LINQ2Dapper封装Model实体类 public class DataType { public int DataTypeId { get; set; } ...
  • WuLex
  • WuLex
  • 2016年09月08日 17:00
  • 4156
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linq入门杂荟
举报原因:
原因补充:

(最多只允许输入30个字)