使用实体框架6.1的通用数据访问助手(代码优先)

介绍

这个帮助器的目标是使用实体框架(CodeFirst)开发一个通用的 - 可重用的数据访问帮助程序,而其动机是使用泛型代理消除冗余代码

帮助者分为两个部分,第一部分是查询(检索)业务,第二个是将数据库的更改保存到同步和异步的数据库中。

背景

这个帮助者提出使用这些技术.NET 4.5(C#5),实体框架6(CodeFirst)。此外,您需要具有关于asyncawait代码的适度知识

详细内容

这里的泛型意味着将泛型应用于采用代理类型的方法Action,以防万一它不返回,或者类型Func返回结果 - 作为一个参数,而这个参数又将类型参数DBContext作为基类继承自具体类。

每个方法根据其作用封装以下逻辑:

  • 启动一个具体的实体框架上下文 using
  • 使用locked(Default)或unlocking(IsolationLevel.ReadUncommitted)表开始事务范围
  • trycatch身体
  • 委托执行
  • 提交和回滚逻辑,以防它是由一组事务组成的原子事务
  • 结果返回类型布尔值,表示查询/保存状态,或使用泛型预定义的类型。
  • 异步逻辑
  • 日志异常

所有这些逻辑不会被写入您的基于业务的数据访问逻辑,因此冗余代码被消除。

动机

当我们编写一个使用EF&Linq访问数据库的简单逻辑时,它看起来像这样:

public static List<Employee> GeAllEmployees()
{
    try
    {
        using (var northwindContext = new NorthwindDBContext())
        {
            var query = from e in northwindContext.Employees select e;
            return query.ToList();
        }
    }
    catch (Exception ex)
    {
        // Log Error
    }
}

所以,我必须使这个代码冗余与一个新的业务(例如GetEmployeeOrders)。另外,如果我必须访问另一个数据库,这意味着另一个DBContext,我必须使这个逻辑冗余!

在这里,通用代表代表作为这两个问题的解决方案。所以,我创建了一个  public static class名为DALHelper包含以下七个static方法。

1查询

所有检索的方法也可用于保存对数据库的更改。

1.1默认值

以下代码片段是锁定表,这是启动新的代码的默认行为 DbContext

public static bool GenericRetrival<T>(Action<T> action) where T : DbContext, new()
{
    try
    {
        using (var context = new T())
        {
            action(context);
            return true;
        }
    }
    catch (Exception ex)
    {
	// Log Error
        return false;
    }
}
用法
public List<Employee> GeAllEmployees()
{
	List<Employee> result= null;
	bool success = DALHelper.GenericRetrival<NorthwindDBContext>((northwindContext) =>
	{
		result = (from e in northwindContext.Employees select e).ToList();
	});
	return result;
}
1.2查询通用结果

这里我们将TResult 类型DBContext的代表标识为类型的泛型,Func返回TResult 类型的对象

public static TResult GenericResultRetrival<T, TResult>(Func<T, TResult> func) where T : DbContext, new()
    where TResult : new()
{
    try
    {
        using (var context = new T())
        {
            TResult res = func(context);
            return res;
        }
    }
    catch (Exception ex)
    {
        // Log Error
        return default(TResult);
    }
}
用法
public List<Employee> GeAllEmployees()
{
	List<Employee> result = DALHelper.GenericResultRetrival<NorthwindDBContext,List<Employee>>((northwindContext) =>
	{
		return (from e in northwindContext.Employees select e).ToList();
	});
	return result;
}
1.3 异步查询
public static async Task<TResult> GenericRetrivalAsync<T, 
	TResult>(Func<T, Task<TResult>> func)
    where T : DbContext, new()
    where TResult : new()
{
    try
    {
        using (var context = new T())
        {
            return await func(context);
        }
    }
    catch (Exception ex)
    {
	// Log Error
        return default(TResult);
    }
}
用法
public async Task<List<Employee>> GetAllEmployeesAsync()
{
    return await DALHelper.GenericRetrivalAsync<NorthwindDBContext, List<Employee>>(async (northwindContext) =>
    {
        return await (from e in northwindContext.Employees select e).ToListAsync();
    });
}
1.4一个长时间的查询,没有异步锁定
public static async Task<TResult> 
GenericResultNoLockLongRetrivalAsync<T,TResult>(Func<T, Task<TResult>> func)
    where T : DbContext, new()
    where TResult : new()
{
    try
    {
        using (var context = new T())
        {
            ((IObjectContextAdapter)context).ObjectContext.CommandTimeout = 0;
            using (var dbContextTransaction = 
            	context.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
            {
                return await func(context);
            }
        }
    }
    catch (Exception exception)
    {
        // Log Error
        return default(TResult);
    }
}
1.5从两个上下文异步查询
public static async Task<object> 
	GenericTwiceContextsRetrivalAsync<T1, T2>(Func<T1, T2, Task<object>> func)
            where T1 : DbContext, new()
            where T2 : DbContext, new()
{
    try
    {
        using (var context1 = new T1())
        {
            using (
                var dbContextTransaction1 = context1.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
            {
                using (var context2 = new T2())
                {
                    using (
                        var dbContextTransaction2 =
                            context2.Database.BeginTransaction(IsolationLevel.ReadUncommitted)
                        )
                    {
                        return await func(context1, context2);
                    }
                }
            }
        }
    }
    catch (Exception exception)
    {
        // Log Error

        return null;
    }
}
用法
public async Task<object> GetDistributedDataAsync()
{
    return await DALHelper.GenericTwiceContextsRetrivalAsync<NorthwindDBContext, AdventureWorkDBContext>(async
        (northwindContext, advantureContext) =>
        {
            var employees = (from e in northwindContext.Employees select e).ToListAsync();
            var cutomers = (from c in advantureContext.Customers select c).ToListAsync();

            await Task.WhenAll(employees, cutomers);
            return new
            {
                EmployeeList = employees.Result,
                PersonList = cutomers.Result
            };
        });
}

所以设计将是:

2储蓄

2.1通用安全储存

我称之为安全,因为它可以将一组事务视为具有提交/回滚逻辑的  原子。 

public static bool GenericSafeTransaction<T>(Action<T> action) where T : DbContext, new()
{
    using (var context = new T())
    {
        using (var dbContextTransaction = context.Database.BeginTransaction())
        {
            try
            {
                action(context);
                dbContextTransaction.Commit();
                return true;
            }
            catch (Exception ex)
            {
                dbContextTransaction.Rollback();
                // Log Error
                return false;
            }
        }
    }
}
用法
public bool AddMultipleRecords(Employee newEmp, Supplier newSup)
{
    return DALHelper.GenericSafeTransaction<NorthwindDBContextgt;(northwindContext =>
    {
        northwindContext.Employees.Add(newEmp);
        northwindContext.SaveChanges();
        northwindContext.Suppliers.Add(newSup);
        northwindContext.SaveChanges();
    });
}
2.2 异步保存
public static async Task<int?> GenericSafeTransactionAsync<T>(Action<T> action)
            where T : DbContext, new()
{
    using (var context = new T())
    {
        using (var dbContextTransaction = context.Database.BeginTransaction())
        {
            try
            {
                action(context);
                int affectedRecords = await context.SaveChangesAsync();
                dbContextTransaction.Commit();
                return affectedRecords;
            }
            catch (Exception ex)
            {
                dbContextTransaction.Rollback();
		// Log Error
                return null;
            }
        }
    }
}
用法
return await DALHelper.GenericSafeTransactionAsync<NorthwindDBContext>( async (northwindContext) =>
{
	northwindContext.Employees.Add(newEmp);
});

【本文由“筱乐微讯账号”发布,2017年10月22日】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值