实体框架连接错误事件

时间:2018-01-30 13:56:16

标签: c# entity-framework entity-framework-6

我正在尝试捕获EF可能在一个地方抛出的所有SQLExceptions(连接错误,超时等)。我在DI中使用了一个工作模式单元,所以没有var using = context例如。在业务逻辑周围使用.Single.ToList等调用。

我是否可以覆盖或注入任何类别的钩子或事件来执行此操作?

2 个答案:

答案 0 :(得分:0)

假设您的工作单元最终调用DbContext.SaveChanges(),您可以使用try-catch包装此调用。

另一个需要开发团队遵守规则的选项是在基础BL类中添加两个方法:IList<T> MaterializeList<T>(IQueriable<T> query)T MaterializeSingle<T>(IQueriable<t> query),它们看起来像这样:

protected IList<T> MaterializeList<T>(IQueriable<T> query) {
    try {
        return query.ToList();
    }
    catch {
        //your error handling code here
    }
}

protected T MaterializeSingle<T>(IQueriable<t> query) {
    try {
        return query.FirstOrDefault();
    }
    catch {
        //your error handling code here
    }
}

然后始终使用这些方法实现。

作为旁注,我尝试在我的数据访问层中保留LINQ to Entities查询,使业务逻辑层不知道数据访问技术。

答案 1 :(得分:0)

有一点工作要做,但这会对你有所帮助:

使用假上下文封装您DbContext并隐藏您的DbSets。您构建了一个新的上下文,它将成为业务逻辑的上下文。这个不能访问DbSets,它向用户显示自定义dbSet。主要工作是构建伪上下文,它需要在真正的dbSet上使用所有方法。

/// <summary>
/// This sould no be used anywhere except in MyDbContext2
/// </summary>
public class MyDbContext : DbContext
{
    public DbSet<SomeTableClass> SomeTable { get; set; }
}

/// <summary>
/// This will be your context in the business-logic
/// </summary>
public class MyDbContext2
{
    private MyDbContext realDb;

    public MyDbContext2(string conStr)
    {
        realDb = new MyDbContext();
    }

    public MyDbSet<SomeTableClass> SomeFakeTable { get; set; }
}

/// <summary>
/// Fake-set with logging
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyDbSet<T> where T : class
{
    private DbSet<T> dbSet;

    public MyDbSet(DbSet<T> realDbSet)
    {
        this.dbSet = realDbSet;
    }

    public List<T> ToList()
    {
        try
        {
            return dbSet.ToList();
        }
        catch (Exception e)
        {
            // Do some logging..
            throw;
        }
    }

    public T SingleOrDefault()
    {
        try
        {
            return dbSet.SingleOrDefault();
        }
        catch (Exception e)
        {
            // Do some logging..
            throw;
        }
    }
}

一个好主意是重命名你DbContext并引入一个旧名称的假名。这样,Visual Studio将向您显示必须实现的方法。