2011-08-15 61 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的一個點。 –