假设我的SQL数据库中有三个表-Users,Books和UsersBooks。
我正在寻找优化Web方法的设计/性能的方法,该方法需要一个用户名列表并返回一个包含用户及其书本的JSON对象。我正在使用Linq2Entities和SQL Server 2008。
这个问题的动机是网络方法被称为很多(并且正在不断增长!),因此我需要找到方法使其变得更加精简和有意义。
这是当前设计的精简版:
private string MyWebMethod(string input) {
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<string> userNames = serializer.Deserialize<List<string>>(input);
using(var db = new dbContext()) {
var usersAndBooks = from u in db.Users
join ub in db.UsersBooks on u.UserId equals ub.UserId
join b in db.Books on ub.BookId equals b.BookId
select new Result { User = u, UsersBooks = ub, Book = b };
var predicate = PredicateBuilder.False<Result>();
// Construct predicate to filter usersAndBooks down to users we care about
foreach(var name in userNames) {
predicate = predicate.Or(r => r.User.UserName.Equals(name));
}
usersAndBooks = usersAndBooks.AsExpandable().Where(predicate);
foreach(var name in userNames) {
// Logic to construct final {User:{Books}} JSON object
}
}
}
为什么不只是使用.Contains
?
var usersAndBooks = from u in db.Users
where userNames.Contains(u.UserName)
join ub in db.UsersBooks on u.UserId equals ub.UserId
join b in db.Books on ub.BookId equals b.BookId
select new Result { User = u, UsersBooks = ub, Book = b };
我认为在这里使用linqkit /谓词生成器/表达式访问器是过大的。您基本上可以IN
使用LINQ来执行SQL子句.Contains
。
数据库对此进行优化要容易得多:
WHERE User.UserName IN ('user1', 'user2', 'user3')
...比这个:
WHERE User.UserName = 'user1' OR User.UserName = 'user2' OR User.UserName = 'user3'
其次,真的有必要遍历结果吗?
foreach(var name in userNames) {
// Logic to construct final {User:{Books}} JSON object
}
...不确定这里的逻辑是什么,但是您可以仅使用另一个进行转换。选择:
// Logic to construct final {User:{Books}} JSON object
var finalOutput = usersAndBooks.Select(x => new ...);
除了缓存或诸如redis之类的其他快速数据传递服务之外,我只能推荐的另一件事是使用Newtonsoft JSON.Net而不是JavaScriptSerializer:
List<string> userNames = JsonConvert.DeserializeObject<List<string>>(input);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句