[英]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.