LINQ to SQL活学活用(3):嗅出“臭味”烟消云散

来源:互联网 发布:淘宝联盟推广位名称 编辑:程序博客网 时间:2024/04/25 21:21

改进

知道程序的“臭味”,我们如何改进呢?想想,通过接口隐藏实体。我们利用接口实现,为Customer创建分部类,创建ICustomer接口,Customer实现ICustomer接口,利用ICustomer接口编写CustomerFacade,根据新的ICustomer接口更新单元测试,而不是上一节的对Customer对象做单元测试,这样客户就不知道数据访问层中具体实现了。这就是我们这一节做的工作。

数据访问层

进一步改进我们的程序,看看数据访问层的类图设计:

架构

1.新建ICustomer接口

public interface ICustomer{    int CustomerId { get; set; }    string FirstName { get; set; }    string LastName { get; set; }}

2.新建分部类Customer实现ICustomer接口

public partial class Customer : ICustomer{}

我在这里这个分部类就空实现了,实际上是数据访问对象DataContext中的Customer类(数据访问对象)实现了这个接口。

3.修改数据访问外观基类

增加一个方法实现IQueryable<T>转换为IList<TInterface>接口

protected IList<TInterface> ConvertToList<TInterface, TConcrete>(    IEnumerable<TConcrete> convertThis)    where TConcrete : TInterface{    if (convertThis == null)    {        return new List<TInterface>();    }    else    {        IList<TInterface> returnValue = new List<TInterface>();        foreach (TConcrete item in convertThis)        {            returnValue.Add(item);        }        return returnValue;    }}

4.修改数据访问外观CustomerFacade

这个类中封装了Customer对象的具体CRUD实现,我们需要修改,实现接口。

Step1:新建临时Customer对象

public ICustomer CreateCustomer(){    return new Customer();}

Step2:按CustomerId获取Customer对象

public ICustomer GetCustomerById(int customerId){    return (from p in DataContext.Customer            where p.CustomerId == customerId            select p).FirstOrDefault();}

Step3:获取Customer对象列表

public IList<ICustomer> GetCustomerList(){    IQueryable<Customer> results =        from p in DataContext.Customer        select p;    return ConvertToList<ICustomer, Customer>(results);}

Step4:更新保存Customer对象

public void UpdateCustomer(ICustomer customer){    Customer tempCustomer = customer as Customer;    if (tempCustomer.CustomerId == 0)    {        DataContext.Customer.InsertOnSubmit(tempCustomer);    }    DataContext.SubmitChanges();}

数据访问层修改完毕了。

单元测试层

只要把相应的数据访问对象换为数据访问对象接口,可以倒置依赖关系从而完全解除对LINQ to SQL的依赖。

Step1:修改创建并保存Customer方法:

private ICustomer CreateAndSaveNewCustomer(string firstName, string lastName){    ICustomer newCustomer = Facade.CreateCustomer();    newCustomer.FirstName = firstName;    newCustomer.LastName = lastName;    Facade.UpdateCustomer(newCustomer);    return newCustomer;}

Step2:修改测试UpdateCustomer()方法:

[Test]public void UpdateCustomerTest(){    ICustomer newCustomer = CreateAndSaveNewCustomer("YJing", "Lee");    Assert.AreNotEqual(0, newCustomer.CustomerId);    Assert.AreEqual("YJing", newCustomer.FirstName);}

Step3:修改GetCustomerByIdTest()方法:

[Test]public void GetCustomerByIdTest(){    ICustomer tempCustomer = CreateAndSaveNewCustomer("YJing", "Lee");    Assert.AreNotEqual(0, tempCustomer.CustomerId);    ICustomer reloaded = Facade.GetCustomerById(tempCustomer.CustomerId);    Assert.IsNotNull(reloaded);    Assert.AreEqual(tempCustomer.CustomerId, reloaded.CustomerId);    Assert.AreSame(tempCustomer, reloaded);}

这篇公布一下这个测试方法结果吧:

测试

Step4:修改获取Customer列表方法

[Test]public void GetListTest(){    List<ICustomer> tempCustomers = new List<ICustomer>();    tempCustomers.Add(CreateAndSaveNewCustomer("YJing", "Lee"));    tempCustomers.Add(CreateAndSaveNewCustomer("li", "yongjing"));    tempCustomers.Add(CreateAndSaveNewCustomer("cnblogs", "com"));    var reloaded = Facade.GetCustomerList();    Assert.IsNotNull(reloaded);    Assert.AreEqual(tempCustomers.Count, reloaded.Count);}

结语

通过这篇的修改,我们程序的“臭味”基本上没有了,依赖关系从原来的对LINQ to SQL的依赖转为接口,客户直接使用接口。下篇就开始扩展吧,看看LINQ to SQL还有什么好东西!

0 0
原创粉丝点击