public static IList<ShopProductCommentVo> Select(int pageSize, int currentPage, string ctype, int shopId, int type, string productGuid) { IList<ShopProductCommentVo> list; if (type == 2) { int id = Convert.ToInt32(productGuid); var query = Context.ShopProductComments .Join(Context.Members, s => s.MemLoginId, m => m.MemLoginId, (s, m) => new { ShopProductComment = s, Member = m }) .Join(Context.GroupProducts, s => s.ShopProductComment.ProductGuid, g => g.ProductGuid, (s, g) => new { s.ShopProductComment, s.Member, GroupProduct = g }) .Where( t => t.GroupProduct.Id == id && t.ShopProductComment.IsAudit == 1 && t.ShopProductComment.ShopId == shopId); switch (ctype) { case "good": query = query.Where(t => t.ShopProductComment.CommentType == 5); break; case "normal": query = query.Where(t => t.ShopProductComment.CommentType == 3); break; case "bad": query = query.Where(t => t.ShopProductComment.CommentType == 1); break; case "addcomment": query = query.Where(t => t.ShopProductComment.ContinueComment != string.Empty); break; } list = query.Skip(currentPage * pageSize).Take(pageSize).Select(t => new ShopProductCommentVo { Pic = t.Member.Photo, Guid = t.ShopProductComment.Guid, Speed = t.ShopProductComment.Speed, Reply = t.ShopProductComment.Reply, ReplyTime = t.ShopProductComment.ReplyTime, IsDelete = t.ShopProductComment.IsDelete, IsNick = t.ShopProductComment.IsNick, SpecValue = t.ShopProductComment.SpecValue, ProductGuid = t.ShopProductComment.ProductGuid, ShopId = t.ShopProductComment.ShopId, ShopLoginId = t.ShopProductComment.ShopLoginId, ShopName = t.ShopProductComment.ShopName, MemLoginId = t.ShopProductComment.MemLoginId, OrderGuid = t.ShopProductComment.OrderGuid, ProductName = t.ShopProductComment.ProductName, ProductPrice = t.ShopProductComment.ProductPrice, IsAudit = t.ShopProductComment.IsAudit, Attitude = t.ShopProductComment.Attitude, BuyerAttitude = t.ShopProductComment.BuyerAttitude, Character = t.ShopProductComment.Character, Comment = t.ShopProductComment.Comment, CommentTime = t.ShopProductComment.CommentTime, CommentType = t.ShopProductComment.CommentType, ContinueComment = t.ShopProductComment.ContinueComment, ContinueReply = t.ShopProductComment.ContinueReply, ContinueReplyTime = t.ShopProductComment.ContinueReplyTime, ContinueState = t.ShopProductComment.ContinueState, ContinueTime = t.ShopProductComment.ContinueTime }).ToList(); } else { var query = Context.ShopProductComments .Join(Context.Members, s => s.MemLoginId, m => m.MemLoginId, (s, m) => new { ShopProductComment = s, Member = m }) .Where( t => t.ShopProductComment.IsAudit == 1 && t.ShopProductComment.ProductGuid == new Guid(productGuid) && t.ShopProductComment.ShopId == shopId); switch (ctype) { case "good": query = query.Where(t => t.ShopProductComment.CommentType == 5); break; case "normal": query = query.Where(t => t.ShopProductComment.CommentType == 3); break; case "bad": query = query.Where(t => t.ShopProductComment.CommentType == 1); break; case "addcomment": query = query.Where(t => t.ShopProductComment.ContinueComment != string.Empty); break; } list = query.Skip(currentPage * pageSize).Take(pageSize) .Select(t => new ShopProductCommentVo { Pic = t.Member.Photo, Guid = t.ShopProductComment.Guid, Speed = t.ShopProductComment.Speed, Reply = t.ShopProductComment.Reply, ReplyTime = t.ShopProductComment.ReplyTime, IsDelete = t.ShopProductComment.IsDelete, IsNick = t.ShopProductComment.IsNick, SpecValue = t.ShopProductComment.SpecValue, ProductGuid = t.ShopProductComment.ProductGuid, ShopId = t.ShopProductComment.ShopId, ShopLoginId = t.ShopProductComment.ShopLoginId, ShopName = t.ShopProductComment.ShopName, MemLoginId = t.ShopProductComment.MemLoginId, OrderGuid = t.ShopProductComment.OrderGuid, ProductName = t.ShopProductComment.ProductName, ProductPrice = t.ShopProductComment.ProductPrice, IsAudit = t.ShopProductComment.IsAudit, Attitude = t.ShopProductComment.Attitude, BuyerAttitude = t.ShopProductComment.BuyerAttitude, Character = t.ShopProductComment.Character, Comment = t.ShopProductComment.Comment, CommentTime = t.ShopProductComment.CommentTime, CommentType = t.ShopProductComment.CommentType, ContinueComment = t.ShopProductComment.ContinueComment, ContinueReply = t.ShopProductComment.ContinueReply, ContinueReplyTime = t.ShopProductComment.ContinueReplyTime, ContinueState = t.ShopProductComment.ContinueState, ContinueTime = t.ShopProductComment.ContinueTime }).ToList(); } return list; }
附图....
这是我的优化方案
后来我才想明白,不一定要jion,只要最终结果正确,能解决问题就行了,不要被jion困住
public enum CType { good = 5, normal = 3, bad = 1, addcomment = -1 } public static IList<ShopProductCommentVo> Select(int pageSize, int currentPage, string ctype, int shopId, int type, string productGuid) { var query = Context.ShopProductComments.Where(t => t.IsAudit == 1 && t.ShopId == shopId); query = type == 2 ? query.Where(t => Context.GroupProducts.Where(g => g.Id == Convert.ToInt32(productGuid)) .Select(g => g.ProductGuid).Contains(t.ProductGuid)) : query.Where(t => t.ProductGuid == new Guid(productGuid)); query = ctype.ToLower().Equals(CType.addcomment.ToString()) ? query.Where(t => t.ContinueComment != string.Empty) : query.Where(t => t.CommentType == (int) Enum.Parse(typeof (CType), ctype)); var query2 = query.Join( Context.Members, s => s.MemLoginId, m => m.MemLoginId, (s, m) => new { s, m }) .Skip(currentPage * pageSize) .Take(pageSize) .Select(t => new ShopProductCommentVo { Pic = t.m.Photo, Guid = t.s.Guid, Speed = t.s.Speed, Reply = t.s.Reply, ReplyTime = t.s.ReplyTime, IsDelete = t.s.IsDelete, IsNick = t.s.IsNick, SpecValue = t.s.SpecValue, ProductGuid = t.s.ProductGuid, ShopId = t.s.ShopId, ShopLoginId = t.s.ShopLoginId, ShopName = t.s.ShopName, MemLoginId = t.s.MemLoginId, OrderGuid = t.s.OrderGuid, ProductName = t.s.ProductName, ProductPrice = t.s.ProductPrice, IsAudit = t.s.IsAudit, Attitude = t.s.Attitude, BuyerAttitude = t.s.BuyerAttitude, Character = t.s.Character, Comment = t.s.Comment, CommentTime = t.s.CommentTime, CommentType = t.s.CommentType, ContinueComment = t.s.ContinueComment, ContinueReply = t.s.ContinueReply, ContinueReplyTime = t.s.ContinueReplyTime, ContinueState = t.s.ContinueState, ContinueTime = t.s.ContinueTime }); return query2.ToList(); }
你需要AutoMapper,当然,其他Mapper也行。
我的重点在于查询条件的简化(优化),而不是想办法去掉Select后面的那一大坨...
当然,用AutoMapper去掉Select后面的一大坨也是不错的,感谢你的推荐.
@VAllen: 上面那一部份,因为你有的时三个类的JOIN,有的是两个类JOIN,没有办法简化,但可以把他们弄到另外一个函数GetQueryObject里面去。
而下面这段SWITCH的
switch (ctype) { case "good": query = query.Where(t => t.ShopProductComment.CommentType == 5); break; case "normal": query = query.Where(t => t.ShopProductComment.CommentType == 3); break; case "bad": query = query.Where(t => t.ShopProductComment.CommentType == 1); break; case "addcomment": query = query.Where(t => t.ShopProductComment.ContinueComment != string.Empty); break; }
整段代码应该可以简化为如下,其中GetQueryObject(type)是自定义函数 :
int id = Convert.ToInt32(productGuid); var query = GetQueryObject(type); if(ctype=="addcomment") { query=query.where("ContinueComment!=null") } else { query=query.where("CommentType=" + cTypeValue) }
@爱编程的大叔: 你把无关痛痒的地方,复杂化了.哥.
可以教一下如何使用AutoMapper对iQueryable<匿名类>进行映射吗?
@VAllen: 如果要用Automapper,你得先看看怎么用,不是这样直接用的。
简化你的MAPPER,你说要简化的是查询条件,
简化你的查询条件,你又说无关痛痒,这就不懂了。
@爱编程的大叔: 在你说Automapper的时候,我就去查相关资料了,大都是类与类之间的映射,看起来比较简单.
而我这个的映射,我就不懂得如何写了.
至于刚才所说的无关痛痒是因为重点在于if,把if解决掉,就可以降低代码重复,接着才考虑用swich还是enum之类的问题..
public static IList<ShopProductCommentVo> Select(int pageSize, int currentPage, string ctype, int shopId, int type, string productGuid)
{
IList<ShopProductCommentVo> list;
if (type == 2)
{
int id = Convert.ToInt32(productGuid);
var query = Context.ShopProductComments
.Join(Context.Members,
s => s.MemLoginId,
m => m.MemLoginId,
(s, m) => new { ShopProductComment = s, Member = m })
.Join(Context.GroupProducts,
s => s.ShopProductComment.ProductGuid,
g => g.ProductGuid,
(s, g) => new { s.ShopProductComment, s.Member, GroupProduct = g })
.Where(
t => t.GroupProduct.Id == id &&
t.ShopProductComment.IsAudit == 1 &&
t.ShopProductComment.ShopId == shopId);
}
else
{
var query = Context.ShopProductComments
.Join(Context.Members,
s => s.MemLoginId,
m => m.MemLoginId,
(s, m) => new { ShopProductComment = s, Member = m })
.Where(
t => t.ShopProductComment.IsAudit == 1 &&
t.ShopProductComment.ProductGuid == new Guid(productGuid) &&
t.ShopProductComment.ShopId == shopId);
}
query= ctype.Equals(CType.AddComment.ToString())
?query.Where(t => t.ShopProductComment.ContinueComment != string.Empty);
:query.Where(t => t.ShopProductComment.CommentType == (int)Enum.Parse(typeof(CType),ctype)));
list = query.Skip(currentPage * pageSize).Take(pageSize).Select(t => new ShopProductCommentVo
{
Pic = t.Member.Photo,
Guid = t.ShopProductComment.Guid,
Speed = t.ShopProductComment.Speed,
Reply = t.ShopProductComment.Reply,
ReplyTime = t.ShopProductComment.ReplyTime,
IsDelete = t.ShopProductComment.IsDelete,
IsNick = t.ShopProductComment.IsNick,
SpecValue = t.ShopProductComment.SpecValue,
ProductGuid = t.ShopProductComment.ProductGuid,
ShopId = t.ShopProductComment.ShopId,
ShopLoginId = t.ShopProductComment.ShopLoginId,
ShopName = t.ShopProductComment.ShopName,
MemLoginId = t.ShopProductComment.MemLoginId,
OrderGuid = t.ShopProductComment.OrderGuid,
ProductName = t.ShopProductComment.ProductName,
ProductPrice = t.ShopProductComment.ProductPrice,
IsAudit = t.ShopProductComment.IsAudit,
Attitude = t.ShopProductComment.Attitude,
BuyerAttitude = t.ShopProductComment.BuyerAttitude,
Character = t.ShopProductComment.Character,
Comment = t.ShopProductComment.Comment,
CommentTime = t.ShopProductComment.CommentTime,
CommentType = t.ShopProductComment.CommentType,
ContinueComment = t.ShopProductComment.ContinueComment,
ContinueReply = t.ShopProductComment.ContinueReply,
ContinueReplyTime = t.ShopProductComment.ContinueReplyTime,
ContinueState = t.ShopProductComment.ContinueState,
ContinueTime = t.ShopProductComment.ContinueTime
}).ToList();
return list;
}
public enum CType{
good=5,
normal=3,
bad=1
addcomment=-1
}
这个query局部变量定义在括号内,是什么飞出来的,求解答
var query判断里的两个抽象出一个类型来,放到判断外边IEnumerable<T> query=null;
@烽火情怀: 没理解你的意思..
@VAllen: 判断最终查出的是同一种类型的。你直接试这个得了。
public static IList<ShopProductCommentVo> Select(int pageSize, int currentPage, string ctype, int shopId, int type, string productGuid)
{
IList<ShopProductCommentVo> list;
var query = type == 2
? Context.ShopProductComments
.Join(Context.Members,
s => s.MemLoginId,
m => m.MemLoginId,
(s, m) => new { ShopProductComment = s, Member = m })
.Join(Context.GroupProducts,
s => s.ShopProductComment.ProductGuid,
g => g.ProductGuid,
(s, g) => new { s.ShopProductComment, s.Member, GroupProduct = g })
.Where(
t => t.GroupProduct.Id == Convert.ToInt32(productGuid) &&
t.ShopProductComment.IsAudit == 1 &&
t.ShopProductComment.ShopId == shopId)
: Context.ShopProductComments
.Join(Context.Members,
s => s.MemLoginId,
m => m.MemLoginId,
(s, m) => new { ShopProductComment = s, Member = m })
.Where(
t => t.ShopProductComment.IsAudit == 1 &&
t.ShopProductComment.ProductGuid == new Guid(productGuid) &&
t.ShopProductComment.ShopId == shopId);
query= ctype.Equals(CType.AddComment.ToString())
?query.Where(t => t.ShopProductComment.ContinueComment != string.Empty);
:query.Where(t => t.ShopProductComment.CommentType == (int)Enum.Parse(typeof(CType),ctype)));
list = query.Skip(currentPage * pageSize).Take(pageSize).Select(t => new ShopProductCommentVo
{
Pic = t.Member.Photo,
Guid = t.ShopProductComment.Guid,
Speed = t.ShopProductComment.Speed,
Reply = t.ShopProductComment.Reply,
ReplyTime = t.ShopProductComment.ReplyTime,
IsDelete = t.ShopProductComment.IsDelete,
IsNick = t.ShopProductComment.IsNick,
SpecValue = t.ShopProductComment.SpecValue,
ProductGuid = t.ShopProductComment.ProductGuid,
ShopId = t.ShopProductComment.ShopId,
ShopLoginId = t.ShopProductComment.ShopLoginId,
ShopName = t.ShopProductComment.ShopName,
MemLoginId = t.ShopProductComment.MemLoginId,
OrderGuid = t.ShopProductComment.OrderGuid,
ProductName = t.ShopProductComment.ProductName,
ProductPrice = t.ShopProductComment.ProductPrice,
IsAudit = t.ShopProductComment.IsAudit,
Attitude = t.ShopProductComment.Attitude,
BuyerAttitude = t.ShopProductComment.BuyerAttitude,
Character = t.ShopProductComment.Character,
Comment = t.ShopProductComment.Comment,
CommentTime = t.ShopProductComment.CommentTime,
CommentType = t.ShopProductComment.CommentType,
ContinueComment = t.ShopProductComment.ContinueComment,
ContinueReply = t.ShopProductComment.ContinueReply,
ContinueReplyTime = t.ShopProductComment.ContinueReplyTime,
ContinueState = t.ShopProductComment.ContinueState,
ContinueTime = t.ShopProductComment.ContinueTime
}).ToList();
return list;
}
public enum CType{
good=5,
normal=3,
bad=1
addcomment=-1
}
@烽火情怀: 这种写法是不支持的,一个是三个类联合的匿名类型,另一个是两个类联合的匿名类型,
所以不能用三元运算符...
编译器无法通过...
@烽火情怀: 很多种写法我的尝试过了,很多次想象新的写法可行,可是写到最后却不行.
我在这个问题上,研究了两天,始终找不到可以简化(优化)的方案.
无奈,才写了这么长的"正确"代码.
然后发到博客园来,寻找高手.
@VAllen: 思路:将判断中的两种类型先统一转成IList<ShopProductCommentVo>,再进行之后的switch判断。
然后再想法把你的Select后面的一大坨给换掉。
@烽火情怀: 呵呵,先转成IList<ShopProductCommentVo>,就意味着,要执行多次数据库查询..
这个不合格
首先看都不看直接来个AutoMapper
第一个回答的仁兄已经跟我提过AutoMapper了...
对象属性映射不是重点..
如何使用AutoMapper对iQueryable<匿名类>进行映射?
你的ctype可以用字典来处理啊,然后就没有switch case了。dic = new Dictionary<string,int>()
ctype不是重点
还有,要注意,有一个是null,所以,如果用字典,也应该是new Dictionary<string,int?>()
@VAllen: 你倒是说,哪个是重点啊~这代码里面不好的部分就是ctype和对new{},还有if else开头那段一样的代码。。先把这些改好了,这段代码就还将就了。
@幻天芒: 主要是代码重复太多,以及if...
解决了if,就可以大大降低代码重复,直接用switch或用Dictionary或用楼上仁兄的enum都不是重点...
@VAllen: 所以关键是讲共同部分只保留一份了。