您的位置:首页 > 其它

什么是LINQ

2010-08-09 19:05 162 查看
LINQ的英文全称是Language Integrated Query,中文翻译为“语言集成查询”。LINQ作为一种查询技术,首先要解决数据源封装的问题,在.NET框架库中,大致使用三大组件来实现这个封装,分别是LINQ to Objects、LINQ to ADO.NET 、LINQ to XML.

LINQ使用开发者熟悉的各种语言关键字和运算符,针对SQL Server、XML文档、内存中支持IEnumerable或泛型IEnumerable<T>接口的任意对象集合进行查询,并且还可以用.NET提供的扩展框架添加更多的数据源,例如MySQL、LiteSql、DB2等。

1.LINQ to Objects

在编程中要经常接触和使用数组、集合等对象,LINQ to Objects可以实现IEnumerable或泛型IEnumerable<T>接口的集合、数组对象进行查询。

在.NET框架中,几乎所有的集合或数组对象都已经全部或部分实现了上述两个接口,可以方便地才程序中的任何位置使用Linq查询这些对象的元素。

如下面的代码:

using System;
using System.Linq;
using System.Collections;

namespace Linq2ObjectsDemo1
{
class Program
{
static void Main(string[] args)
{
//定义个字符串数组
string[] friends = { "霓裳公主", "萧家大小姐", "出云公主", "苗族圣姑", "高丽公主" };

Console.WriteLine("按照传统的方法查找/n");

//初始化一个新的集合,用于存储后面查询到的元素
ArrayList values = new ArrayList();

//使用传统的方法查找字符串包含“公主”的词组。
//遍历数组把复合条件的元素放入values集合中
foreach (string word in friends)
{
if (word.IndexOf("公主") > -1)
values.Add(word);
}

//对结果进行排序
values.Sort();

//遍历并输出查询结果
foreach (string w in values)
Console.WriteLine(w);

Console.WriteLine("/n------------------------/n");
Console.WriteLine("使用LINQ方法查询/n");

//使用LINQ技术查找包含“公主”的词组,并对结果进行排序。
var value = from v in friends
where v.IndexOf("公主") > -1
orderby v
select v;

//遍历并输出查询结果
foreach (var w in value)
Console.WriteLine(w);

//为了方便查看运行结果,等待用户按键后结束程序
Console.ReadKey();
}
}
}


2.LINQ to ADO.NET

用LINQ技术查询关系型数据库,需要使用LINQ to ADO.NET,它还细分为LINQ to SQL、LINQ to DataSet以及在Visual Studio2008发布后开发的LINQ to Entities:

LINQ to SQL是通过使用开发者建立的一个映射SQL Server中的数据表,被称作实体类的类型,来完成对数据库的查询、修改、删除操作。

LINQ to DataSet用来查询DataSet数据集或从数据断开连接的数据。

LINQ to Entities的用途跟LINQ to SQL类似,但比LINQ to SQL功能更加复杂强大,例如,在一个 实体类中映射多个数据库表格和它们之间的关系,用LINQ 查询Miscrosoft SQL Server系列产品以外的关系 数据库等。

下面的Windows窗体 应用程序,显示了LINQ to SQL的应用

AddressBookController.cs文件:

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace AddressBook
{
/// <summary>
/// 电话薄控制器
/// </summary>
public class AddressBookController
{
public AddressBookController()
{
this.dataContext = new AddressBookClassesDataContext();
this.BookBindingList = this.dataContext.TabAddressBook.GetNewBindingList();
}

~AddressBookController()
{
if (this.dataContext != null)
this.dataContext.Dispose();
}

/// <summary>
/// LINQ to SQL 数据库上下文
/// </summary>
public AddressBookClassesDataContext dataContext;

/// <summary>
/// 提供给控件的数据绑定对象
/// </summary>
public IBindingList BookBindingList { get; private set; }

/// <summary>
/// 添加新记录
/// </summary>
/// <param name="item"></param>
public void New(TabAddressBook item)
{
if (item != null)
{
this.dataContext.TabAddressBook.InsertOnSubmit(item);
this.dataContext.SubmitChanges();
this.BookBindingList = this.dataContext.TabAddressBook.GetNewBindingList();
}
}

/// <summary>
/// 修改记录
/// </summary>
/// <param name="item"></param>
public void Update(TabAddressBook item)
{
if (item != null)
{

var query = from i in this.dataContext.TabAddressBook
where i.ab_id == item.ab_id
select i;

foreach (var q in query)
{
q.ab_add = item.ab_add;
q.ab_age = item.ab_age;
q.ab_com = item.ab_com;
q.ab_dub = item.ab_dub;
q.ab_name = item.ab_name;
q.ab_sex = item.ab_sex;
q.ab_tel = item.ab_tel;
}

this.dataContext.SubmitChanges();
this.BookBindingList = this.dataContext.TabAddressBook.GetNewBindingList();
}
}

/// <summary>
/// 删除一个电话簿记录
/// </summary>
public void Delete(TabAddressBook item)
{
if (item != null)
{

var query = from i in this.dataContext.TabAddressBook
where i.ab_id == item.ab_id
select i;

foreach (var q in query)
this.dataContext.TabAddressBook.DeleteOnSubmit(q);

this.dataContext.SubmitChanges();
this.BookBindingList = this.dataContext.TabAddressBook.GetNewBindingList();
}
}

/// <summary>
/// 搜索
/// </summary>
public IEnumerable<TabAddressBook> Search(string p)
{
//利用LINQ搜索数据
var query = from q in this.dataContext.TabAddressBook
where q.ab_name.IndexOf(p) > -1
select q;

return query;
}
}
}


MainForm.cs文件:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace AddressBook
{
public partial class MainForm : Form
{
/// <summary>
/// 定义并初始化控制器
/// </summary>
private AddressBookController abctl = new AddressBookController();

/// <summary>
/// 窗体状态枚举
/// </summary>
private enum FormStatus { Show, Modition, New, NoData, LoadError };

/// <summary>
/// 定义并初始化窗体状态
/// </summary>
private FormStatus fs = FormStatus.Show;

/// <summary>
/// 暂存正在操作的数据
/// </summary>
private TabAddressBook nowItem = null;

public MainForm()
{
InitializeComponent();
bind();
}

/// <summary>
/// 重新绑定ListBox
/// </summary>
private void rebindlstbox()
{
this.rebindlstbox(abctl.BookBindingList);
}
private void rebindlstbox(object datasource)
{
this.addlst.DataSource = null;
this.addlst.DataSource = datasource;
this.addlst.DisplayMember = "ab_name";
}

/// <summary>
/// 控件数据绑定
/// </summary>
private void bindctl(object datasource)
{
this.txtage.DataBindings.Clear();
this.txtage.DataBindings.Add(new Binding("Text", datasource, "ab_age", true));
this.txtname.DataBindings.Clear();
this.txtname.DataBindings.Add(new Binding("Text", datasource, "ab_name"));
this.txtadd.DataBindings.Clear();
this.txtadd.DataBindings.Add(new Binding("Text", datasource, "ab_add"));
this.txtcom.DataBindings.Clear();
this.txtcom.DataBindings.Add(new Binding("Text", datasource, "ab_com"));
this.txtdub.DataBindings.Clear();
this.txtdub.DataBindings.Add(new Binding("Text", datasource, "ab_dub"));
this.txttel.DataBindings.Clear();
this.txttel.DataBindings.Add(new Binding("Text", datasource, "ab_tel"));
this.cbsex.DataBindings.Clear();
this.cbsex.DataBindings.Add(new Binding("Text", datasource, "ab_sex"));
}

/// <summary>
/// 绑定数据
/// </summary>
private void bind()
{
//数据绑定到控件
this.rebindlstbox();
this.bindctl(abctl.BookBindingList);

if (abctl.BookBindingList.Count == 0)
this.fs = FormStatus.NoData;

this.swControls();
}

/// <summary>
/// 根据状态修改控件显示
/// </summary>
private void swControls()
{
this.SuspendLayout();
switch (this.fs)
{
case FormStatus.Show:
this.edCtl(false);
this.addlst.Enabled = true;
this.txtsec.ReadOnly = false;
this.butdel.Enabled = true;
this.butnew.Enabled = true;
this.butnew.Text = "新建";
this.butsave.Enabled = true;
break;

case FormStatus.Modition:
case FormStatus.New:
this.edCtl(true);
this.butdel.Enabled = false;
this.butnew.Enabled = true;
this.butnew.Text = "放弃";
this.addlst.Enabled = false;
this.txtsec.ReadOnly = true;
break;

case FormStatus.NoData:
this.edCtl(false);
this.butnew.Enabled = true;
break;

case FormStatus.LoadError:
this.edCtl(false);
break;
}

this.ResumeLayout(false);
this.PerformLayout();
}

/// <summary>
/// 控制控件Enabled状态
/// </summary>
/// <param name="op"></param>
private void edCtl(bool op)
{
foreach (Control ctl in this.Controls)
{
if (ctl.GetType() == typeof(TextBox))
{
((TextBox)ctl).ReadOnly = !op;
}
else if (ctl.GetType() != typeof(Label))
{
ctl.Enabled = op;
}
}
}

/// <summary>
///  新建、放弃按钮事件处理
/// </summary>
private void butnew_Click(object sender, EventArgs e)
{
if (this.fs == FormStatus.Show)
{
//新建处理
this.fs = FormStatus.New;
TabAddressBook tb = new TabAddressBook() { ab_name = "新建用户", ab_sex = "女" };
this.nowItem = tb;
this.abctl.New(tb);
this.BindingContext[this.abctl.BookBindingList].Position = this.abctl.BookBindingList.Count;

}
else
{
//放弃处理
if (this.fs == FormStatus.New)
{
this.abctl.Delete(this.nowItem);
this.BindingContext[this.abctl.BookBindingList].Position = this.abctl.BookBindingList.Count;
}

this.fs = FormStatus.Show;
}

//重新绑定数据
this.bind();

this.txtname.Focus();
}

/// <summary>
/// 修改、保存按钮事件处理
/// </summary>
private void butsave_Click(object sender, EventArgs e)
{
if (this.fs == FormStatus.Show)
{
if (this.addlst.SelectedItem != null)
{
//修改处理
this.nowItem = this.addlst.SelectedItem as TabAddressBook;
this.fs = FormStatus.Modition;
}
}
else
{
//保存处理
//转到控制器中使用LINQ to SQL 保存修改到数据库
this.abctl.Update(this.nowItem);

this.fs = FormStatus.Show;
}

//控制控件状态
this.swControls();
this.txtname.Focus();
}

/// <summary>
/// 删除按钮事件处理
/// </summary>
private void butdel_Click(object sender, EventArgs e)
{
//转到控制器中使用LINQ to SQL 从数据库删除
if (this.addlst.SelectedItem != null)
{
this.abctl.Delete((TabAddressBook)this.addlst.SelectedItem);
this.bind();
}
}

/// <summary>
/// 搜索框事件处理
/// </summary>
private void txtsec_TextChanged(object sender, EventArgs e)
{
if (this.fs == FormStatus.Show)
{
if (this.abctl.BookBindingList.Count > 0)
{
if (this.txtsec.Text.Length > 0)
{
//转到控制器中使用LINQ搜索
IEnumerable<TabAddressBook> book = this.abctl.Search(this.txtsec.Text);

//将查询结果绑定到控件
this.rebindlstbox(book);
this.bindctl(book);
}
else
{
//恢复ListBox的数据绑定
this.bind();
}
}
}
}
}
}


3.LINQ to XML

XML应用已经非常的普遍,常见的Internet网页文件,聚合RSS文件、程序配置文件,WebService以及最新格式的Miscrosoft Office Word文件都是基于XML的,

使用LINQ to XML可以访问和修改内存中的文档对象模型(DOM)。相比DOM,LINQ to XML是一种更加轻量级的模型,创建、修改、查询更加方便

下面的windows窗体应用程序演示了LINQ to XML的应用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;

namespace DomViewer
{

/// <summary>
/// RSS DOM 查看器
/// </summary>
public partial class Viewer : Form
{
public Viewer()
{
InitializeComponent();
}

/// <summary>
/// 获取按钮事件处理
/// </summary>
private void butget_Click(object sender, EventArgs e)
{
this.getrss();
}

/// <summary>
/// 地址输入框事件处理
/// </summary>
private void txturl_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
this.getrss();
}

/// <summary>
/// 处理TreeView展开事件
/// </summary>
private void tvdom_AfterExpand(object sender, TreeViewEventArgs e)
{
if (e.Node != null)
{
XElement tnel = e.Node.Tag as XElement;
if (tnel != null)
{
// 根据TreeView节点上存储的XML节点用LINQ查询其子节点
var els = from el in tnel.Elements()
select el;

this.appendtree(els, e.Node.Nodes, tnel);
}
}
}

/// <summary>
/// 处理TreeView事件,选择节点立即展开
/// </summary>
private void tvdom_AfterSelect(object sender, TreeViewEventArgs e)
{
e.Node.Expand();
}

/// <summary>
/// 或RSS文件并转换为XML文档并加载到TreeView控件中
/// </summary>
private void getrss()
{
try
{
//从网址加载Rss文件
XElement doc = XElement.Load(this.txturl.Text, LoadOptions.None);

//用LINQ检索全部子节点
var els = from el in doc.Elements()
select el;

this.appendtree(els, this.tvdom.Nodes, null);
}
catch (Exception error)
{
MessageBox.Show(error.Message, "加载出错");
}
}

/// <summary>
/// 把XML节点的显示在TreeView上
/// 如果XML节点没有子节点则显示XML节点的Value值
/// </summary>
private void appendtree(IEnumerable<XElement> els, TreeNodeCollection tnc, XElement tnel)
{
tnc.Clear();
if (els.Count<XElement>() == 0 && tnel != null)
{
tnc.Add(new TreeNode(tnel.Value));
return;
}
foreach (var el in els)
{
TreeNode tn = new TreeNode(el.Name.LocalName, new TreeNode[] { new TreeNode(string.Empty) });
tn.Tag = el;
tnc.Add(tn);
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: