首页 新闻 会员 周边

用Linq写的代码,求简化,太多冗余代码了...

0
悬赏园豆:20 [已解决问题] 解决于 2014-12-05 17:26
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;
}

附图....

VAllen的主页 VAllen | 初学一级 | 园豆:94
提问于:2014-12-05 15:04
< >
分享
最佳答案
0

这是我的优化方案

后来我才想明白,不一定要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();
}
VAllen | 初学一级 |园豆:94 | 2014-12-05 17:21
其他回答(5)
0

你需要AutoMapper,当然,其他Mapper也行。

收获园豆:7
爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-05 15:13

我的重点在于查询条件的简化(优化),而不是想办法去掉Select后面的那一大坨...

当然,用AutoMapper去掉Select后面的一大坨也是不错的,感谢你的推荐.

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 15:29

@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)
        }
支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-05 16:30

@爱编程的大叔: 你把无关痛痒的地方,复杂化了.哥.

可以教一下如何使用AutoMapper对iQueryable<匿名类>进行映射吗?

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 17:01

@VAllen: 如果要用Automapper,你得先看看怎么用,不是这样直接用的。

简化你的MAPPER,你说要简化的是查询条件,

简化你的查询条件,你又说无关痛痒,这就不懂了。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-05 17:13

@爱编程的大叔: 在你说Automapper的时候,我就去查相关资料了,大都是类与类之间的映射,看起来比较简单.

而我这个的映射,我就不懂得如何写了.

至于刚才所说的无关痛痒是因为重点在于if,把if解决掉,就可以降低代码重复,接着才考虑用swich还是enum之类的问题..

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 17:20
0



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
}

收获园豆:7
烽火情怀 | 园豆:380 (菜鸟二级) | 2014-12-05 15:52

这个query局部变量定义在括号内,是什么飞出来的,求解答

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 15:56

var query判断里的两个抽象出一个类型来,放到判断外边IEnumerable<T> query=null;

支持(0) 反对(0) 烽火情怀 | 园豆:380 (菜鸟二级) | 2014-12-05 15:56

@烽火情怀: 没理解你的意思..

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:00

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

支持(0) 反对(0) 烽火情怀 | 园豆:380 (菜鸟二级) | 2014-12-05 16:02

@烽火情怀: 这种写法是不支持的,一个是三个类联合的匿名类型,另一个是两个类联合的匿名类型,

所以不能用三元运算符...

编译器无法通过...

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:08

@烽火情怀: 很多种写法我的尝试过了,很多次想象新的写法可行,可是写到最后却不行.

我在这个问题上,研究了两天,始终找不到可以简化(优化)的方案.

无奈,才写了这么长的"正确"代码.

然后发到博客园来,寻找高手.

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:13

@VAllen: 思路:将判断中的两种类型先统一转成IList<ShopProductCommentVo>,再进行之后的switch判断。

然后再想法把你的Select后面的一大坨给换掉。

支持(0) 反对(0) 烽火情怀 | 园豆:380 (菜鸟二级) | 2014-12-05 16:23

@烽火情怀: 呵呵,先转成IList<ShopProductCommentVo>,就意味着,要执行多次数据库查询..

这个不合格

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 17:00
0

有种写文章不带标点,一口气读下来要憋死的感觉

aspnet | 园豆:79 (初学一级) | 2014-12-05 16:09

呵呵..

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:14
0

首先看都不看直接来个AutoMapper

收获园豆:1
Halower | 园豆:1723 (小虾三级) | 2014-12-05 16:30

第一个回答的仁兄已经跟我提过AutoMapper了...

对象属性映射不是重点..

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:55

如何使用AutoMapper对iQueryable<匿名类>进行映射?

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:57
0

你的ctype可以用字典来处理啊,然后就没有switch case了。dic = new Dictionary<string,int>()

收获园豆:5
幻天芒 | 园豆:37175 (高人七级) | 2014-12-05 16:32

ctype不是重点

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:54

还有,要注意,有一个是null,所以,如果用字典,也应该是new Dictionary<string,int?>()

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 16:58

@VAllen: 你倒是说,哪个是重点啊~这代码里面不好的部分就是ctype和对new{},还有if else开头那段一样的代码。。先把这些改好了,这段代码就还将就了。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2014-12-05 17:08

@幻天芒: 主要是代码重复太多,以及if...

解决了if,就可以大大降低代码重复,直接用switch或用Dictionary或用楼上仁兄的enum都不是重点...

支持(0) 反对(0) VAllen | 园豆:94 (初学一级) | 2014-12-05 17:17

@VAllen: 所以关键是讲共同部分只保留一份了。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2014-12-06 08:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册