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

Fra*_*sco 5 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
}
Run Code Online (Sandbox Code Playgroud)

我最终得到这个匿名类型,一切都很好.现在有些东西让我调整了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
    }
}
Run Code Online (Sandbox Code Playgroud)

因为在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
}
Run Code Online (Sandbox Code Playgroud)

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

我想避免为了维护而重复代码,但我不知道该怎么做.我觉得我错过了一些基本的东西,但找不到什么,所以你的帮助是受欢迎和赞赏的.

非常感谢你的帮助.

xan*_*tos 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
}
Run Code Online (Sandbox Code Playgroud)

.Where()方法不会更改查询的"类型"!

请注意,这是合法的:

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
}
Run Code Online (Sandbox Code Playgroud)

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