簡體   English   中英

將Linq重構為Sql

[英]Refactoring Linq to Sql

有沒有一種方法可以將linq重構為sql並利用后期評估的優勢? 有沒有一種方法可以重用對象初始化代碼?

我有一些業務對象,這些對象保留在數據庫中,並通過單獨的linq to 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進行sql后期評估。 如果您觀看數據庫查詢,則僅選中的列是我感興趣的列(在hydrateUser中列為ID,FirstName等)。 很好,因為我可以重用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;
}

當我想使用hydrateUser並且還對相關對象進行水合時,樣本2開始下降。 例如,為權限列表充水。 我現在必須剝離一個完整的單獨功能來進行額外的保濕。 如果要初始化的屬性更多,則不那么理想。

樣品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 ,雖然它似乎可以滿足我的需要,但我還是希望“開箱即用”。

目前,整體架構尚待辯論。

您是否考慮過向用戶顯式加載Permissions對象?

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.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM