Linq+Xml学习笔记

 

      Linq是第一次接触,此前一直用个的sql。这次写一个WPF的小程序,WPF的绑定和一般C#程序的绑定不同,以往直接绑定到datatable上,很方便。WPF中多需要转换成对象集合,不方便,就在网上搜索了下Linq的用法,通过这个程序进行了一下整理。

      个人感觉,Linq对Xml的操作比Xpath对Xml的操作要方便,对数据库进行操作还是看个人的喜好了。Linq对多表的操作还是感觉相当麻烦的,我个人还是倾向sql。

      首先,我建立了一个Dataitem.xml的文件,放在bin目录下

      数据的操作无非就是读、写、删、改。新增了一个Linqtoxml的类,在类里添加了以下方法:

      加载文件:

 

  
    
public static string Getxmlfile()
{
return System.AppDomain.CurrentDomain.BaseDirectory + " Dataitem.xml " ;
}

 

 

  读:

 

代码
   
     
public static List < Dataitem > Getalldata()
{
XDocument doc
= XDocument.Load(Getxmlfile());
var items
= (from i in doc.Descendants( " 数据项 " ) select i).Take( 20 );
List
< Dataitem > list = new List < Dataitem > ();
foreach (var item in items)
{
XElement p
= item;
Dataitem it
= new Dataitem();
it.Id
= Convert.ToInt32(p.Attribute( " 编号 " ).Value);
it.Client
= p.Element( " 客户 " ).Value;
it.Product
= p.Element( " 产品 " ).Value;
it.Batch
= p.Element( " 批次 " ).Value;
it.Team
= p.Element( " 班组 " ).Value;
it.Total
= Convert.ToDouble(p.Element( " 总数 " ).Value);
it.Receive
= Convert.ToDouble(p.Element( " 接收 " ).Value);
it.Inspection
= Convert.ToDouble(p.Element( " 实检 " ).Value);
it.Bugnum
= Convert.ToDouble(p.Element( " 缺陷 " ).Value);
it.Inspector
= p.Element( " 检验 " ).Value;
it.Inspectionday
= p.Element( " 日期 " ).Value;
it.Bugdescription
= p.Element( " 缺陷描述 " ).Value;
it.Bugresponsible
= p.Element( " 责任人员 " ).Value;
it.Bugwith
= p.Element( " 缺陷处理 " ).Value;
list.Add(it);
}
return list;
}

 

       写:

 

代码
   
     
public static void Adddata(Dataitem it)
{
XDocument doc
= XDocument.Load(Getxmlfile());
XElement ele
= new XElement( " 数据项 " ,
new XAttribute( " 编号 " ,it.Id),
new XElement( " 客户 " ,it.Client),
new XElement( " 产品 " ,it.Product),
new XElement( " 批次 " ,it.Batch),
new XElement( " 班组 " ,it.Team),
new XElement( " 总数 " ,it.Total),
new XElement( " 接收 " ,it.Receive),
new XElement( " 实检 " ,it.Inspection),
new XElement( " 缺陷 " ,it.Bugnum),
new XElement( " 检验 " ,it.Inspector),
new XElement( " 日期 " ,it.Inspectionday),
new XElement( " 缺陷描述 " ,it.Bugdescription),
new XElement( " 责任人员 " ,it.Bugresponsible),
new XElement( " 缺陷处理 " ,it.Bugwith)
);
doc.Root.AddFirst(ele);
doc.Save(Getxmlfile());
}

 

      删:

 

代码
   
     
public static void deldata( int id)
{
XDocument doc
= XDocument.Load(Getxmlfile());
var items
= from i in doc.Descendants( " 数据项 " ) where Convert.ToInt32(i.Attribute( " 编号 " ).Value) == id select i;
XElement p
= null ;
foreach (var item in items)
{
p
= item;
}
p.Remove();
doc.Save(Getxmlfile());
}

 

      改:

 

代码
   
     
public static void editdata(Dataitem it)
{
XDocument doc
= XDocument.Load(Getxmlfile());
var items
= from i in doc.Descendants( " 数据项 " ) where Convert.ToInt32(i.Attribute( " 编号 " ).Value) == it.Id select i;
XElement p
= null ;
foreach (var item in items)
{
p
= item;
}
p.SetElementValue(
" 客户 " ,it.Client);
p.SetElementValue(
" 产品 " ,it.Product);
p.SetElementValue(
" 批次 " ,it.Batch);
p.SetElementValue(
" 班组 " ,it.Team);
p.SetElementValue(
" 总数 " ,it.Total);
p.SetElementValue(
" 接收 " ,it.Receive);
p.SetElementValue(
" 实检 " ,it.Inspection);
p.SetElementValue(
" 缺陷 " ,it.Bugnum);
p.SetElementValue(
" 检验 " ,it.Inspector);
p.SetElementValue(
" 日期 " ,it.Inspectionday);
p.SetElementValue(
" 缺陷描述 " ,it.Bugdescription);
p.SetElementValue(
" 责任人员 " ,it.Bugresponsible);
p.SetElementValue(
" 缺陷处理 " ,it.Bugwith);
doc.Save(Getxmlfile());
}

 

      还有个是进行了一个分组的统计,这个用法和sql的语法是不一样的,综合了网上的代码(很多不能用)进行了修改,反正是可以用的。呵呵,能搞定才能松口气。

      分组汇总:

 

代码
   
     
public static List < Statresult > Statdata(DateTime dt1,DateTime dt2)
{
XDocument doc
= XDocument.Load(Getxmlfile());
var items
= from i in doc.Descendants( " 数据项 " )
where Convert.ToDateTime(i.Element( " 日期 " ).Value) >= dt1 && Convert.ToDateTime(i.Element( " 日期 " ).Value) <= dt2
group i by i.Element(
" 客户 " ).Value into k select new
{
client
= k.Key,
total
= k.Sum(m => Convert.ToDouble(m.Element( " 总数 " ).Value)),
receiv
= k.Sum(m => Convert.ToDouble(m.Element( " 接收 " ).Value)),
rates
= Math.Round(k.Sum(m => Convert.ToDouble(m.Element( " 接收 " ).Value)) / k.Sum(m => Convert.ToDouble(m.Element( " 总数 " ).Value)), 4 ) * 100 ,
inspect
= k.Sum(m => Convert.ToDouble(m.Element( " 实检 " ).Value)),
bugs
= k.Sum(m => Convert.ToDouble(m.Element( " 缺陷 " ).Value)),
qualified
= Math.Round((k.Sum(m => Convert.ToDouble(m.Element( " 实检 " ).Value)) - k.Sum(m => Convert.ToDouble(m.Element( " 缺陷 " ).Value))) / k.Sum(m => Convert.ToDouble(m.Element( " 实检 " ).Value)), 4 ) * 100
};
List
< Statresult > list = new List < Statresult > ();
foreach (var item in items)
{
Statresult st
= new Statresult();
st.Client
= item.client;
st.Total
= item.total;
st.Receive
= item.receiv;
st.Rates
= item.rates;
st.Inspection
= item.inspect;
st.Bugnum
= item.bugs;
st.Qualified
= item.qualified;
list.Add(st);
}
return list;
}

 

      使用Linq还有一个问题,就是实现sql中的拼接字符串。比如要搜索,条件拼接后传给逻辑层的方法进行调用。Linq中where关键字后不能使用字符串,跟的是一个bool型的表达式。困扰了许久,只能把实现直接写在应用层,用的是Linq的Where方法。使用Linq的时候要注意,select、where等等都有大写开头的方法,和小写的关键字是不一样的,这也是我后来发现的。Linq里面的各种内置方法用的都是C#的,和sql不用,这点也要注意

      字符串的拼接的解决办法:

 

代码
   
     
private void butqry_Click( object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
XDocument doc = XDocument.Load(Linqtoxml.Getxmlfile());
var items
= from i in doc.Descendants( " 数据项 " ) select i;

if (txt14.Text.Trim() != "" )
items
= items.Where(k => k.Element( " 客户 " ).Value.Contains(txt14.Text.Trim()));
if (txt15.Text.Trim() != "" )
items
= items.Where(k => k.Element( " 产品 " ).Value.Contains(txt15.Text.Trim()));
if (txt16.Text.Trim() != "" )
items
= items.Where(k => k.Element( " 批次 " ).Value.Contains(txt16.Text.Trim()));
if (r1.IsChecked.Value && txt17.Text.Trim() != "" )
{
try
{
Convert.ToDateTime(txt17.Text.Trim());
items
= items.Where(k => Convert.ToDateTime(k.Element( " 日期 " ).Value) >= Convert.ToDateTime(txt17.Text.Trim()));
}
catch
{
MessageBox.Show(
" 第4个文本框只能输入日期! " , " 注意 " ,MessageBoxButton.OK,MessageBoxImage.Information);
return ;
}
}
else if (r2.IsChecked.Value && txt18.Text.Trim() != "" )
{
try
{
Convert.ToDateTime(txt18.Text.Trim());
items
= items.Where(k => Convert.ToDateTime(k.Element( " 日期 " ).Value) <= Convert.ToDateTime(txt18.Text.Trim()));
}
catch
{
MessageBox.Show(
" 第5个文本框只能输入日期! " , " 注意 " ,MessageBoxButton.OK,MessageBoxImage.Information);
return ;
}
}
else if (r3.IsChecked.Value && txt17.Text.Trim() != "" && txt18.Text.Trim() != "" )
{
try
{
Convert.ToDateTime(txt17.Text.Trim());
Convert.ToDateTime(txt18.Text.Trim());
items
= items.Where(k => Convert.ToDateTime(k.Element( " 日期 " ).Value) >= Convert.ToDateTime(txt17.Text.Trim()) &&
Convert.ToDateTime(k.Element(
" 日期 " ).Value) <= Convert.ToDateTime(txt18.Text.Trim()));
}
catch
{
MessageBox.Show(
" 最后2个文本框只能输入日期! " , " 注意 " ,MessageBoxButton.OK,MessageBoxImage.Information);
return ;
}
}
if (r4.IsChecked.Value)
items
= items.Where(k => Convert.ToDouble(k.Element( " 缺陷 " ).Value) <= 0 );
else if (r5.IsChecked.Value)
items
= items.Where(k => Convert.ToDouble(k.Element( " 缺陷 " ).Value) > 0 );

List
< Dataitem > list = new List < Dataitem > ();
foreach (var item in items)
{
XElement p
= item;
Dataitem it
= new Dataitem();
it.Id
= Convert.ToInt32(p.Attribute( " 编号 " ).Value);
it.Client
= p.Element( " 客户 " ).Value;
it.Product
= p.Element( " 产品 " ).Value;
it.Batch
= p.Element( " 批次 " ).Value;
it.Team
= p.Element( " 班组 " ).Value;
it.Total
= Convert.ToDouble(p.Element( " 总数 " ).Value);
it.Receive
= Convert.ToDouble(p.Element( " 接收 " ).Value);
it.Inspection
= Convert.ToDouble(p.Element( " 实检 " ).Value);
it.Bugnum
= Convert.ToDouble(p.Element( " 缺陷 " ).Value);
it.Inspector
= p.Element( " 检验 " ).Value;
it.Inspectionday
= p.Element( " 日期 " ).Value;
it.Bugdescription
= p.Element( " 缺陷描述 " ).Value;
it.Bugresponsible
= p.Element( " 责任人员 " ).Value;
it.Bugwith
= p.Element( " 缺陷处理 " ).Value;
list.Add(it);
}
if (list != null )
datamain.ItemsSource
= list;
else
MessageBox.Show(
" 没有找到符合条件的数据! " , " 注意 " ,MessageBoxButton.OK,MessageBoxImage.Information);

 

      个人使用的一点总结,希望和刚接触的朋友一起学习

你可能感兴趣的:(LINQ)