c#列表< string>以Lambda表达式与启动器示例:Refactor来处理列表 [英] c# List<string> to Lambda Expression with starter example: Refactor to handle the List

查看:975
本文介绍了c#列表< string>以Lambda表达式与启动器示例:Refactor来处理列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个:

List<string> fields;

fields[0] = "firstFieldName";
fields[1] = "secondFieldName";
...
fields[n] = "nthFieldName";

我想得到这个:

var selector = p => new {p.firstField, p.secondField, ..., p.nthFieldName}

// selector is of type Expression<Func<Entity, object>>

GoofBallLogic 这个代码是simliar,最后是$ code> p => p.column

GoofBallLogic had this code that was simliar, ending up with p => p.column

// Entity is an object in a diagram from Entity Framework 4
var p = Expression.Parameter(typeof(Entity, "p");

var selector = Expression.Lambda<Func<Entity, string>(
    Expression.Property(p, columnToGroupBy), p );

编辑:我正在努力完成

我有一个通用存储库:

public class Repository<E, C> : IRepository<E,C>
{
    private C _dc {get;set;} // ObjectContext (Entity Framework 4)
    private string _entityName {get;set;}
    public string entityKeyName {get;private set;}
    public List<string> entityKeys {get;private set;}
    public Expression<Func<E, object>> entityKey {get;private set;}
    private EntityContainer _containerName {get;set;}

    public Repository(C myDC)
    {   _dc = myDC; // TODO: check for null

        // Name of "this" ObjectContext
        _containerName = _dc.MetadataWorkspace.GetEntityContainer(
            _dc.DefaultContainerName, DataSpace.CSpace);

        // Name of "this" Entity
        _entityName = _containerName.BaseEntitySets
            .Where(p => p.ElementType.Name == typeof (E).Name)
            .Select( p => p.Name).FirstOrDefault();

        // String list of the keys
        entityKeys = _containerName
            .BaseEntitySets.First(meta => meta.ElementType.Name == 
                typeof(E).Name)
            .ElementType.KeyMembers.Select(k => k.Name).ToList();

        // Thanks Jon Skeet for this cool comma sep list formula
        entityKeyName = string.Join(",", entityKeys.ToArray() );  

        entityKey = Expression.Lambda<Func<E, object>> ... 

如何将entityKey设置为可用于
的对象一个OrderBy语句,因为Linq to Entities需要
在做一个.Skip()之前订购一组。Take()

What to do to set entityKey as an object that can be used in an OrderBy statement since Linq to Entities requires ordering a set before doing a .Skip().Take()

编辑:

令人惊讶的是,Orderby可以这样做:

Amazingly, Orderby can take this:

p => "field1,field2,field3"

哪些允许我的代码执行,但实际上并不排序项通过字段值。这是TDD的第一步,我猜:使用一个文字。

Which allows my code to execute but doesn't actually order the items by the field values. It's a first step in TDD I guess: use a literal.

推荐答案

我发现这是一个有趣的问题,花了一些时间来出来,发现一个比较容易的方式来做。

I found this an interesting problem and took some time to figure it out, and found a relatively easy way to do it.

无论如何,这里是一个例子,说明如何做一个单一的字段排序(我将使用你的第一个字段)如果你想排序更多的字段,你也必须为他们创建表达式,并在通常的OrderBy(xxx)之后使用.ThenBy(xxx)。

Anyhow, here's an example on how to do a single field sort (i'll use your first field), if you want to sort on more fields you'll have to create expressions for them too and use .ThenBy(xxx) after the usual OrderBy(xxx).

    // Create a parameter which passes the object
    ParameterExpression param = Expression.Parameter(typeof(E), "a");

    // Create body of lambda expression
    Expression body = Expression.PropertyOrField(param, fieldname);

    // Create lambda function
    Expression<Func<E, string>> exp = Expression.Lambda<Func<E, string>>(body, param);

    // Compile it so we can use it
    Func<E, string> orderFunc = exp.Compile();

现在,您可以执行一个OrderBy(orderFunc),它将按照名为字段名。唯一的缺点是它只适用于字符串字段(表达式的返回值)。可能也可以解决这个问题。

Now you can do an OrderBy(orderFunc) and it'll sort the list by the property named in fieldname. Only downside being it only works for string fields (return value of expression). Could probably work around that too though.

修正为使用任何IComparable类型:

Fixed to work with any IComparable type:

        // Create a parameter which passes the field
        ParameterExpression param = Expression.Parameter(typeof(E), "a");

        // Create body of lambda expression
        Expression body = Expression.TypeAs(Expression.PropertyOrField(param, fieldname), typeof(IComparable));

        // Create lambda function
        Expression<Func<E, IComparable>> exp = Expression.Lambda<Func<E, IComparable>>(body, param);

        // Compile it so we can use it
        Func<E, IComparable> orderFunc = exp.Compile();

这篇关于c#列表&lt; string&gt;以Lambda表达式与启动器示例:Refactor来处理列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆