首先说一下这篇文章的目的,这篇文章的目的是为了学习微软强推的Odata 协议访问数据库的新方式和 使用泛型来简化数据库的操作的两个目的。
Odata协议在此就不赘述,大家可以百度。在使用VS2012的过程中偶然发现了 wcf data service
当然在创建Wcf Data Service之前需要创建 ADO.NET实体数据模型,这个大家用Linq to Entities 这么多年也都知道。
然后点击添加之后生成一个web service文件
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
namespace IDMS_WEBmvc
{
public class MyWcfDataService : DataService<IDMSEntities>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
}
这里以Silverlight 异步访问数据库为准进行举例。
这里谈谈我的想法,大家都知道如果使用Linq 语句操作数据库进行查询的时候,需要指定数据库的某个表。
winform里的同步的写法
Entities En = new Entities();
var a = (from m in En.BU_MASTER where m.XX = "xx" select m).Tolist();
var b = (from m in En.BU_CONTAINER where m.XX ="xx" select m).Tolist();
Silverlight 里的异步写法
DomainContext db = new DomainContext();
var a = from m in db.GetBU_MASTERQuery() select m;
LoadOperation<BU_MASTER> lp = db.load(a);
lp.Completed += lp_Completed;
void lp_Completed(object sender, EventArgs e)
{
LoadOperation<BU_MASTER> lp = sender as LoadOperation<BU_MASTER>;
List<BU_MASTER> lis = lp.Entities.ToList();
}
不管是同步还是异步访问数据库,都需要指定到具体的类型。也就是说查每一个数据表中的数据都需要重新写一遍查询方法。有没有一个通用的办法,能使得查询
任意表的数据都使用同一个办法,这样大大的减少了代码量,同时也使得逻辑上易于控制。这不也是面向对象需要干的事情之一么。
这个时候就想到了泛型。(以异步访问举例)
如下代码
using LujinSdk.Framework.Base;
using System;
using System.Collections.ObjectModel;
using System.Net;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using System.Collections.Generic;
using IDMS_GPS.MyDataService;
using System.Data.Services.Client;
using IDMS_WEBmvc;
using System.Reflection;
namespace IDMS_GPS.Framework.Base
{
public class IDMSDataModelClass<T> : MyBaseNewModelClass where T : System.ComponentModel.INotifyPropertyChanged, new()
{
public IDMSDataModelClass()
{
LoadDataSouceMethod();
}
IDMSEntities IDMSDomainContext;
public ObservableCollection<T> dataSource = new ObservableCollection<T>();
public void LoadDataSouceMethod()
{
try
{
IDMSDomainContext = new IDMSEntities(new Uri("MyWcfDataService.svc", UriKind.Relative));//调用刚才创建的Wcf Data Services
var query = IDMSDomainContext.T_GPSLATEST;
Uri uri = dataServiceQuery.RequestUri;
IDMSDomainContext.BeginExecute<T>(uri,
(ar) =>
{
var plist = IDMSDomainContext.EndExecute<T>(ar).ToList(); dataSource = new ObservableCollection<T>(plist); //取到的数据返回到dataSource
}, null);
}
catch (Exception ex)
{
}
}
public global::System.Data.Services.Client.DataServiceQuery<T> dataServiceQuery
{
get
{
if ((this._dataServiceQuery == null))
{
try
{
string type = typeof(T).ToString();
int a= type.LastIndexOf(".")+1;
int b = type.Length - a;
string info = type.Substring(a, b);
this._dataServiceQuery = IDMSDomainContext.CreateQuery<T>(info);
} catch (Exception ex)
{
}
}
return this._dataServiceQuery;
}
}
private global::System.Data.Services.Client.DataServiceQuery<T> _dataServiceQuery;
}
}
这样通过泛型的办法就能实现访问所有的数据表都使用同一个办法,继承该基类,指定T,即可。我们来看一下如何使用这个基类,下面的类继承该基类,<>内指定 T,
直接调用刚才定义的dataSource,同样,访问其他数据库表只需要指定其他的T。
public class EditFenseChildViewModel : IDMSDataModelClass<IDMS_GPS.MyDataService.T_GPSLATEST> public EditFenseChildViewModel() {IDMS_GPS.MyDataService.T_GPSLATEST> = dataSouce;}