【Design】数据访问层 抽象接口 简单工厂 抽象工厂

数据访问层,访问数据的方式有很多种,可以用EF,ADO.NET等,在项目实现中如果突然想改数据访问方式,如果没有好的设计,改起来是很麻烦的。

可以用抽象接口的方式来实现

首先,定义一个IBaseDal接口

public interface IBaseDal<T> where T : class, new()
{
    /// <summary>
    /// 添加
    /// </summary>
    T Add(T entity);

    /// <summary>
    /// 修改
    /// </summary>
    bool Update(T entity);

    /// <summary>
    /// 删除
    /// </summary>
    bool Delete(T entity);

    /// <summary>
    /// 通过参数获取信息
    /// </summary>
    IQueryable<T> GetEntities(Expression<Func<T, bool>> whereLambda);

    /// <summary>
    /// 分页
    /// </summary>
    /// <typeparam name="S">排序对象</typeparam>
    /// <param name="pageSize">页数据个数</param>
    /// <param name="pageIndex">页码</param>
    /// <param name="total">数据总量</param>
    /// <param name="whereLambda">条件参数</param>
    /// <param name="orderByLambda">排序参数</param>
    /// <param name="isAsc">是否升序</param>
    /// <returns></returns>
    IQueryable<T> GetPageEntities<S>(int pageSize, int pageIndex, out int total,
       Expression<Func<T, bool>> whereLambda,
       Expression<Func<T, S>> orderByLambda,
       bool isAsc);
}

IUserInfoDal 继承IBaseDal

public  interface IUserInfoDal : IBaseDal<UserInfo>
{
}

IOrderInfoDal 继承IBaseDal

public  interface IOrderInfoDal:IBaseDal<OrderInfo>
{
}

BaseDal

public class BaseDal<T> where T : class, new()
{
    DataModelContainer db = new DataModelContainer();

    /// <summary>
    /// 添加
    /// </summary>
    public T Add(T entity)
    {
        db.Set<T>().Add(entity);
        db.SaveChanges();
        return entity;
    }

    /// <summary>
    /// 修改
    /// </summary>
    public bool Update(T entity)
    {
        db.Entry(entity).State = EntityState.Modified;
        return db.SaveChanges() > 0;
    }

    /// <summary>
    /// 删除
    /// </summary>
    public bool Delete(T entity)
    {
        db.Entry(entity).State = EntityState.Deleted;
        return db.SaveChanges() > 0;
    }

    /// <summary>
    /// 通过参数获取信息
    /// </summary>
    public IQueryable<T> GetEntities(Expression<Func<T, bool>> whereLambda)
    {
        return db.Set<T>().Where(whereLambda).AsQueryable();
    }

    /// <summary>
    /// 分页
    /// </summary>
    /// <typeparam name="S">排序对象</typeparam>
    /// <param name="pageSize">页数据个数</param>
    /// <param name="pageIndex">页码</param>
    /// <param name="total">数据总量</param>
    /// <param name="whereLambda">条件参数</param>
    /// <param name="orderByLambda">排序参数</param>
    /// <param name="isAsc">是否升序</param>
    /// <returns></returns>
    public IQueryable<T> GetPageEntities<S>(int pageSize, int pageIndex, out int total,
        Expression<Func<T, bool>> whereLambda,
        Expression<Func<T, S>> orderByLambda,
        bool isAsc)
    {
        total = db.Set<T>().Where(whereLambda).Count();

        if (isAsc)
        {
            var temp = db.Set<T>().Where(whereLambda)
                .OrderBy(orderByLambda)
                .Skip(pageSize * (pageIndex - 1))
                .Take(pageSize).AsQueryable();
            return temp;
        }
        else
        {
            var temp = db.Set<T>().Where(whereLambda)
            .OrderByDescending(orderByLambda)
            .Skip(pageSize * (pageIndex - 1))
            .Take(pageSize).AsQueryable();
            return temp;
        }

    }
}

UserInfoDal 继承BaseDal

public class UserInfoDal : BaseDal<UserInfo>, IUserInfoDal
{
}

OrderInfoDal 继承BaseDal

public class OrderInfoDal : BaseDal<OrderInfo>,IOrderInfoDal
{
}

 

这样一来,只要通过调用接口方法就好了

IUserInfoDal userInfoDal = new UserInfoDal();

但是这样,还是有问题,如果多处调用UserInfoDal的话,修改了数据访问方式,那么所有的UserInfoDal都要修改

那怎么解决这个问题呢,可以用简单工厂实现

 

简单工厂

public class DalFactory
{
    public static IUserInfoDal GetUserInfoDal()
    {
        return new UserInfoDal();
    }

    public static IOrderInfoDal GetOrderInfoDal()
    {
        return new OrderInfoDal();
    }
}

UserInfoService

public class UserInfoService
{
    IUserInfoDal userInfoDal = DalFactory.GetUserInfoDal();

    public UserInfo Add(UserInfo userInfo)
    {
        return userInfoDal.Add(userInfo);
    }
}

OrderInfoService

public class OrderInfoService
{
    IOrderInfoDal orderInfoDal = DalFactory.GetOrderInfoDal();

    public OrderInfo Add(OrderInfo orderInfo)
    {
        return orderInfoDal.Add(orderInfo);
    }
}

这样只要修改工厂模式的实例化就好了

这样设计还是有问题,就是更改时每一个Dal都要更改,UserInfoDal和OrderInfoDal都要更改实例

 

我们可以通过抽象工厂解决这个问题

具体实现可以通过反射实现

 

抽象工厂

首先,在UI项目中,Web.config配置文件中的appSettings添加配置

<add key="DalAssemlyName" value="Wang.OA.EFDAL" />

用反射实现

public class StaticDalFactory
{
   static string assemlyName = System.Configuration.ConfigurationManager.AppSettings["DalAssemlyName"];

    public static IUserInfoDal GetUserInfoDal()
    {
        return Assembly.Load(assemlyName).CreateInstance(assemlyName + ".UserInfoDal") as IUserInfoDal;
    }

    public static IOrderInfoDal GetOrderInfoDal()
    {
        return Assembly.Load(assemlyName).CreateInstance(assemlyName + ".OrderInfoDal") as IOrderInfoDal;
    }
}

这样更改数据访问只要更改配置文件就可以了

 

相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页