2011-08-15 62 views
4

我有许多的方法是这样的:EF4上下文创建一个方法

public IEnumerable<Director> GetAllDirectors() 
    { 
     using (var dbContext = new BodModelContainer()) 
     { 
      return dbContext.Members.OfType<Director>().ToList(); 
     } 
    } 

..或者这个..

public Member GetMemberById(int memberId) 
    { 
     using(var dbContext = new BodModelContainer()) 
     { 
      return dbContext.Members.Find(new[] {memberId}); 
     } 
    } 

,或者:

public SomeType GetOrDoSomethingWithDbBySomethingElse(T1 t1var, T2, T2 var, ...) 
    { 
     using(var dbContext = new BodModelContainer()) 
     { 
      return dbContext.SomeType.DoSomething(); 
     } 
    } 

所以我想整理所有这些方法都是这样的:

// create db context here 
    public void InDb(Func<BodModelContainer, out SomeGenericType???> workingWithDb) 
    { 
     using(var dbContext = new BodModelContainer()) 
     { 
      workingWithDb(dbContext); 
     } 
    } 

    // using it like 
    public Member GetMemberById(int memberId) 
    { 
      InDb((dbContext) => 
      { 
        return dbContext.Members.Find(new[] { memberId }); 
      }); 
    } 

问题:如何使这样的通用InDb方法,什么是SomeGenericType???

+0

这看起来像不可读的抽象 – Eranga

+0

Eranga,一些来源编辑。现在它更易读吗?或者这是个坏主意? –

回答

3

它看起来像你描述的实际问题是,你不能弄清楚如何设置的返回类型Func<>。为了能够使这个通用的,你需要使InDb也需要一个通用类型。

public TRet InDb<TRet>(Func<BodModelContainer, TRet> workingWithDb) { 
    TRet ret = default(TRet); 
    using (var dbContext = new BodModelContainer()) { 
    ret = workingWithDb(dbContext); 
    } 
    return ret; 
} 

public Member GetMemberById(int memberId) { 
    return InDb(dbContext => { return dbContext.Members.Find(new[] { memberId }); }); 
} 

应工作(这里所有的代码是未经测试),或使用匿名方法,你可以有一个局部变量,使净做所有的肮脏的工作。

public void InDb(Action<BodModelContainer> workingWithDb) { 
    using (var dbContext = new BodModelContainer()) { 
    workingWithDb(dbContext); 
    } 
} 

public Member GetMemberById(int memberId) { 
    Member member; 
    InDb(dbContext => { member = dbContext.Members.Find(new[] { memberId }); }); 
    return member; 
} 

当然,这一切都这样说,我不知道是不是这个水平重定向/抽象是非常有用的 - 你正在做的稍微但可以察觉的增益(如果有的话)复杂。除非有很多工作正在建立并拆除InDb中使用的dbContext,否则我认为这不是很有帮助。

+1

Drat - 你打败了我。我的回答基本上与你的相同,所以我删除了它。但我认为这种事情非常有用,我一直都这样做。它抽象(复杂的和重复的)设置/拆卸代码,让我们只处理找到成员的代码的语法。看着相同的代码重复的代码,从心理上将代码与工作代码分开,在几个小时后往往让我头痛。 :) – HiredMind

+0

@HiredMind:我同意,如果涉及到一些实际的设置和拆卸,它们肯定会有用。如果它真的只是封装了一个“使用”语句,我不知道如何用另一个替代重复代码有助于 - 除非您计划在将来扩展。话虽如此,我已经明确使用这种方法来将多个操作组合在一起,只需要中间操作就可以改变。 :) – Joshua

+0

@Joshua其实我的情况更复杂。它不仅仅是'var dbContext = new BodModelContainer()',而且还有解析连接字符串。这是以单独的方法提出“使用”块的第一点。第二个 - 创建dbContext的一个点。 –