2009-09-22 28 views
2

有沒有辦法將linq重構爲sql並利用後期評估?有沒有辦法重用對象的initilizer代碼?將Linq重構爲SQL

我有一個業務對象是堅持在數據庫中,並通過一個單獨的linq sql層水合。

我希望能夠重複執行完全相同的事情的多個查詢中的代碼。我想重用的查詢部分是對象創建部分。我還想繼續利用後期評估(僅從數據庫中獲取我想要的列)。

下面給出的示例非常簡單,其中一些名稱已更改爲保護無辜者。

樣品1

void GetUserById(Guid userId) 
{ 
    IQueryable<LinqLayer.User> x = 
     from user in dataContext.Users 
     where user.UserID == userId 
     select user; 

    IQueryable<BusinessLayer.User> y = hydrateUser(x); 

    // Acutally execute the query against the database. 
    BusinessLayer.User user = y.First(); 
} 

void GetUserByName(string name) 
{ 
    IQueryable<LinqUser> x = 
     from user in dataContext.Users 
     where user.FirstName == name 
     select user; 

    IQueryable<User> y = hydrateUser(x); 

    // Acutally execute the query against the database. 
    User user = y.First(); 
} 

IQueryable<User> hydrateUser(IQueryable<LinqUser> x) 
{ 
    IQueryable<User> y; 
     y = from item in x 
     select new User 
     { 
      ID = item.UserID, 
      FirstName = item.FirstName, 
      MiddleName = item.MiddleName, 
      LastName = item.LastName, 
     }; 
    return y; 
} 

幾件事情在樣品1回事在這個例子中,我能夠利用LINQ to SQL的評價晚了。如果您查看數據庫查詢,則選擇的唯一列是我感興趣的列(在hydrateUser中列爲ID,名字等)。這很好,因爲我可以重用hydrateUser中的代碼。

示例2:

IQueryable<User> hydrateUser(IQueryable<LinqUser> x) 
{ 
    IQueryable<User> y; 
     y = from item in x 
     select new User 
     { 
      ID = item.UserID, 
      FirstName = item.FirstName, 
      MiddleName = item.MiddleName, 
      LastName = item.LastName, 
      ... Big long list of properties 
     }; 
    return y; 
} 

IQueryable<User> hydrateUserWithPermissions(IQueryable<LinqUser> x) 
{ 
    IQueryable<User> y; 
     y = from item in x 
     select new User 
     { 
      ID = item.UserID, 
      FirstName = item.FirstName, 
      MiddleName = item.MiddleName, 
      LastName = item.LastName, 
      ... Big long list of properties 
      PermissionList = item.Permissions 
     }; 
    return y; 
} 

樣品2點開始倒下時,我想用hydrateUser,也滋潤相關的對象。例如,補充一系列權限。現在我必須完成一個完全獨立的功能,即額外的水合作用。如果我有更多的屬性正在初始化,這是不太理想的。

樣品3

IQueryable<User> hydratePermissions(IQueryable<LinqUser> x) 
{ 
    IQueryable<User> y; 
     y = from item in x 
     select new User 
     { 
      PermissionList = item.Permissions 
     }; 
    return y; 
} 

IQueryable<User> hydrateUser(IQueryable<LinqUser> x) 
{ 
    IQueryable<User> y; 
     y = from item in x 
     select new User 
     { 
      ID = item.UserID, 
      FirstName = item.FirstName, 
      MiddleName = item.MiddleName, 
      LastName = item.LastName, 
      ... Big long list of properties 
     }; 
    return y; 
} 

我想做什麼就能做的是建立查詢了樣3.代碼不知怎的,試圖利用這兩種功能的優勢。 並且只做一次數據庫訪問。但是,這不起作用。

樣品4

User newUpUserFromLinqUser(LinqUser item) 
{ 
    y = new User 
     { 
      ID = item.UserID, 
      FirstName = item.FirstName, 
      MiddleName = item.MiddleName, 
      LastName = item.LastName, 
     }; 
    return y; 
} 

樣品4接近我想要的東西,但失去了表達的評價,認爲LINQ to SQL的使用做後期評估。所有的字段都會返回到查詢中。更糟的是,如果像這樣的代碼是一個孩子的關係,那麼每個孩子都會對數據庫進行調用。這在我們的情況下是不可接受的。

其他注意事項

帶寬是一個溢價。我們精確地控制數據傳輸的方式,因此查詢儘可能精簡非常重要。

我看過LinqKit雖然看起來它可能適用於我所需要的,但我更喜歡「開箱即用」。

在這個時候,整體架構沒有爭議。

+0

我正在嘗試使您的示例3的正面或反面。第一種方法是獲取用戶的權限集合,第二種獲取實際用戶的權限集合?爲什麼不把PermissionList = item.Permissions添加到第二個方法? –

+0

示例3實際上不起作用。但是,這是我想*要做的。基本上,我想避免多餘的代碼。你提到的情況在樣本2中有所描述。 –

+0

我相信我沒有有效地傳達我的問題,所以我放棄了這個問題。此外,我不相信我想要做的事是可能的。感謝大家的幫助。 –

回答

0

你看過顯式加載與您的用戶的權限對象?

using (var db = new dbContext()) 
{ 
    DataLoadOptions dlo = new DataLoadOptions(); 
    dlo.LoadWith<LinqUser>(lu => lu.Permissions); 
    db.LoadOptions = dlo; 
    //Execute code, knowing that when you retrieve users, it will also retrieve their permissions. 
} 
+0

雖然這沒有得到我想要的,但我會給你一個答案,因爲你是唯一回答的人。 –