3

我可能有这样的函数调用:

foo(**new {x.ID,x.Name}**);

LINQ

(IQueryable<SomeTableName>).where(x=>x.ID>1).select(x=>**new {x.ID,x.Name}**);

是否可以用函数、表达式或变量替换"new {x.ID,x.Name}"部分,所以我可以不时更改,只在一个地方?谢谢你。

我知道我可以制作一个表达式,它只能在 LINQ 中使用

public static Func<SomeTableName, Object> Select_RS_Food = x => new { x.ID,x.Name };

但我也想用于普通的匿名对象创建。像:

foo(CreateMyObject(x));

更新

当前的:

return new { myTable.ID, myTable.Name};
//And
db.SomeTable.Select (x=> new { myTable.ID, myTable.Name));

预计:

return SomeMagicCode;
//And
db.SomeTable.Select (x=> SomeMagicCode);
4

1 回答 1

3

您可以像这样定义一个帮助器类,以允许您在创建时仅指定一些泛型类型参数Func<T, R>

public static class Funk<T>
{
    public static Func<T, R> Make<R>(Func<T, R> func)
    {
        return func;
    }
}

并像这样使用它:

var selector = Funk<SomeTableName>.Make(x => new {x.ID, x.Name});
var result = db.SomeTable.Where(x => x.ID>1).Select(selector);

这利用类型推断来确定返回类型,因此您只需定义输入类型 ( SomeTableName)。var关键字使变量selector隐式键入,您不必指定Func<SomeTableName, _AnonymousType1_>. 您现在可以selector在多个查询中重用。

但是,您将无法将其保存为类的属性或字段,因为类型成员不支持隐式类型。如果您希望能够重用此选择功能,则必须使用命名类型,或者可能dynamic——但我不希望这适用于任何当前的 ORM。

对于其他 lambda 表达式 ( x => x.ID == 1and x => x.ID > 1),不涉及匿名类型,因此您可以简单地执行以下操作:

public static Func<SomeTableName, bool> IDEquals1 = x => x.ID == 1;
public static Func<SomeTableName, bool> IDGreaterThan1 = x => x.ID == 1;

但顺便说一句,如果您使用类似 ORM 的实体框架,您可能需要使用 anExpression来代替。也许是这样的:

public static Expression<Func<T, bool>> IDEquals1 = x => x.ID == 1;

甚至这样:

public interface IHasID 
{
    int ID { get; }
}

public SomeTableName : IHasID { ... }

public static Expression<Func<T, bool>> IDEquals1<T>() where T : IHasID
{
     return x => x.ID == 1;
}
于 2013-06-28T17:05:02.590 回答