根据不同的条件创建匿名类型并将其强制转换为类

时间:2015-05-22 11:30:38

标签: c# lambda anonymous-types

我现在有这个问题,但今天我到了临界点,我正在寻求你的帮助。

假设我有这段代码:

var query = DbContext.Table.Where(x => x.z == true).Select(x => new { x.a, x.b, x.c });
foreach(var item in query)
{
    // Do the work
}

我最终得到了这种匿名类型,一切都很好。现在有些东西让我调整了Where子句,所以我必须根据条件做出不同的查询,这是我真的很沮丧的地方:

if(something)
{
    var query = DbContext.Table.Where(x => x.z == true && x.zz == false).Select(x => new { x.a, x.b, x.c });
    foreach(var item in query)
    {
        // Do the work
    }
}
else
{
    var query = DbContext.Table.Where(x => x.z == true).Select(x => new { x.a, x.b, x.c });
    foreach(var item in query)
    {
        // Do the work
    }
}

因为要在foreach周期完成的工作完全相同,我不应该重复它。

因此,我没有使用匿名类型,而是声明了一个新类并尝试了这个:

class MyQuery
{
    public int a { get; set; }
    public string b { get; set; }
    public decimal? c { get; set; }
}

IQueryable<MyQuery> query = null;

if(something)
{
    query = (IQueryable<MyQuery>)DbContext.Table.Where(x => x.z == true && x.zz == false).Select(x => new { x.a, x.b, x.c });
}
else
{
    query = (IQueryable<MyQuery>)DbContext.Table.Where(x => x.z == true).Select(x => new { x.a, x.b, x.c });
}

foreach(var item in query)
{
    // Do the work
}

但现在我抛出了'System.InvalidCastException',因为我仍然得到一个匿名类型,显然它不能被投入到我的班级中。

我想避免为了维护而重复代码,但我不知道该怎么做。我觉得我在这里遗漏了一些基本但却无法找到的东西,所以欢迎你的帮助和赞赏。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:9)

你过度复杂了:

IQueryable<MyQuery> query = DbContext.Table;

if (something)
{
    query = query.Where(x => x.z == true && x.zz == false)
}
else
{
    query = query.Where(x => x.z == true);
}

var result = query.Select(x => new { x.a, x.b, x.c });

foreach (var item in result)
{
    // Do the work
}

.Where()方法不会更改&#34;类型&#34;查询!

请注意这是合法的:

var query = DbContext.Table.Select(x => new { x.a, x.b, x.c });

if (something)
{
    query = DbContext.Table.Where(x => x.z == true && x.zz == false).Select(x => new { x.a, x.b, x.c });
}
else
{
    query = DbContext.Table.Where(x => x.z == true).Select(x => new { x.a, x.b, x.c });
}

foreach (var item in query)
{
    // Do the work
}

我使用的事实是在同一个程序集中具有相同参数(参数的相同名称,相同类型的参数,相同数量的参数)的匿名类型是&#34;统一&#34;由C#编译器。我只将此行var query = DbContext.Table.Select(x => new { x.a, x.b, x.c });用于&#34;给&#34; var变量的类型。然后我用其他查询完全覆盖查询,因为各种.Select(x => new { x.a, x.b, x.c });&#34;生成&#34;相同(匿名)类型的对象。

答案 1 :(得分:2)

您可以修改Where条件以匹配案例或其他情况。这样,您不再需要担心重复代码或创建仅在此方法上使用的另一个类。

var query = DbContext.Table.Where(x => something && (x.z == true && x.zz == false) || !something && (x.z == true)).Select(x => new { x.a, x.b, x.c });
foreach(var item in query)
{
    // Do the work
}

或者您可以添加三元比较 @Rawling如何提及。

var query = DbContext.Table.Where(x => something ? (x.z == true && x.zz == false) : (x.z == true)).Select(x => new { x.a, x.b, x.c });
foreach(var item in query)
{
    // Do the work
}