1

我想动态添加 .Select 语句,但编译器只允许我在当前范围内构建这些语句。我知道 linqkit,它可能是一个解决方案,但我不想添加任何外部功能。我如何避免我现在拥有的这种代码重复:

 if (request.Equals("some text"))
        {
            var filter = commonFilter.GroupBy(x => new
                {
                    x.Timestamp.Year,
                    x.Timestamp.Month,
                })
                .Select(g => new
                {
                    Year = g.Key.Year,
                    Month = g.Key.Month,
                    TotErr = g.Count(),

                    column1 = g.Sum(o => o.Process.Contains("something") ? 1 : 0),
                    column2= g.Sum(o => o.Process.Contains(".something1") ? 1 : 0),
                    column3= g.Sum(o => o.Process.Contains(".something2") ? 1 : 0),
                    column4= g.Sum(o => o.Process.Contains("something3") ? 1 : 0),
                    column5= g.Sum(o => o.Process.Contains(".something4") ? 1 : 0),
                    column6 = g.Sum(o => o.Process.Contains(".something5") ? 1 : 0),
                    column7= g.Sum(o => o.Process.Contains(".something6") ? 1 : 0),
                    column8= g.Sum(o => o.Process.Contains(".something7") ? 1 : 0),
                    column9= g.Sum(o => o.Process.Contains(".something8") ? 1 : 0),

                    NumOrgs = g.Select(l => l.OrganizationId).Distinct().Count(),
                    NumUsers = g.Select(l => l.UserId).Distinct().Count(),

                });

            return filter.AsPa......;//not important right now
        }
        //Same thing again but slightly different
        else if (request.Equals("some other text"))
        {
            var filter = commonFilter.GroupBy(x => new
                {
                    x.Timestamp.Year,
                    x.Timestamp.Month,
                    x.Timestamp.Day
                })
                .Select(g => new
                {
                    Year = g.Key.Year,
                    Month = g.Key.Month,
                    Day= g.Key.Day,
                    TotErr = g.Count(),

                    column1 = g.Sum(o => o.Process.Contains("something") ? 1 : 0),
                    column2= g.Sum(o => o.Process.Contains(".something1") ? 1 : 0),
                    column3= g.Sum(o => o.Process.Contains(".something2") ? 1 : 0),
                    column4= g.Sum(o => o.Process.Contains("something3") ? 1 : 0),
                    column5= g.Sum(o => o.Process.Contains(".something4") ? 1 : 0),
                    column6 = g.Sum(o => o.Process.Contains(".something5") ? 1 : 0),
                    column7= g.Sum(o => o.Process.Contains(".something6") ? 1 : 0),
                    column8= g.Sum(o => o.Process.Contains(".something7") ? 1 : 0),
                    column9= g.Sum(o => o.Process.Contains(".something8") ? 1 : 0),

                    NumOrgs = g.Select(l => l.OrganizationId).Distinct().Count(),
                    NumUsers = g.Select(l => l.UserId).Distinct().Count(),

                });

            return filter.AsPa......;//not important right now
        }
4

2 回答 2

1

如果要维护 Anonymous 类型,可以使用 InternalsVisibleToAttribute 以允许单独的公共库与匿名类型一起使用。

我以前这样做是为了使用 EF 数据源为数据网格创建一个通用过滤库,但它确实涉及一定程度的反射和从通用 System.Linq.Expression 组件构建表达式,所以这可能不值得,除非你有很多您想要执行此操作的实例。

查看 msdn 信息:

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx

如果选择模式更可预测,您可能不需要表达式部分,但在这种情况下,最终只使用公共类而不是匿名类可能更简单。

编辑:“无法将匿名转换为 x”类型错误意味着您还没有完全/正确地摆脱匿名。

在您拥有 new { ...whatever... } 的每个位置中,您正在创建一个匿名类型。如果您为每个具有正确属性的类创建类以匹配您分配的内容,那么您只需更改一些看起来像

new {x=1,y=2}

读书

new somenewclass() {x=1,x=2}

假设您已在其他地方定义

public class somenewclass
{
    public int x {get;set;}
    public int y {get;set;}
}
于 2012-06-18T14:35:56.433 回答
0

你可以这样做,

  var Query = commonFilter.Select(g => new
            {
                Year = g.Key.Year,
                Month = g.Key.Month,
                Day= g.Key.Day,
                TotErr = g.Count(),

                column1 = g.Sum(o => o.Process.Contains("something") ? 1 : 0),
                column2= g.Sum(o => o.Process.Contains(".something1") ? 1 : 0),
                column3= g.Sum(o => o.Process.Contains(".something2") ? 1 : 0),
                column4= g.Sum(o => o.Process.Contains("something3") ? 1 : 0),
                column5= g.Sum(o => o.Process.Contains(".something4") ? 1 : 0),
                column6 = g.Sum(o => o.Process.Contains(".something5") ? 1 : 0),
                column7= g.Sum(o => o.Process.Contains(".something6") ? 1 : 0),
                column8= g.Sum(o => o.Process.Contains(".something7") ? 1 : 0),
                column9= g.Sum(o => o.Process.Contains(".something8") ? 1 : 0),

                NumOrgs = g.Select(l => l.OrganizationId).Distinct().Count(),
                NumUsers = g.Select(l => l.UserId).Distinct().Count(),

            });
    if (request.Equals("some text"))
    {
        var filter = Query.GroupBy(x => new
            {
                x.Timestamp.Year,
                x.Timestamp.Month,
            }) ;
    }
    //Same thing again but slightly different
    else if (request.Equals("some other text"))
    {
        var filter = Query.GroupBy(x => new
            {
                x.Timestamp.Year,
                x.Timestamp.Month,
                x.Timestamp.Day
            });
    }
于 2012-06-18T14:19:56.583 回答