在Linq投影中根据名称选择属性

时间:2010-08-04 10:36:02

标签: c# linq syntax c#-4.0

我有一堂课说

public class CostStore
{
    int DirectorateId { get; set; }

    decimal NewCar { get; set; }

    decimal ContractorNew { get; set; }

    decimal ContractorRenew { get; set; }

    decimal ContractorLost { get; set; }

    decimal ContractorStolen { get; set; }

    decimal InternalNew { get; set; }

    decimal InternalRenew { get; set; }

    decimal InternalLost { get; set; }

    decimal InternalStolen { get; set; }        
}

在我的控制器中我想找出说

var c = from p in _service.List().Where (condition) p.InternalNew/InternalRenew

(etc)属性基于如下函数中的会话变量,如何在linq语句中执行此操作...任何想法(_service.List()列出了类CostStore的IEnumerable

private string FindProperty()
{
    switch (Session[Constants.FORMSESSIONKEY].ToString())
    {
        case Constants.NEWAPP:
            return "InternalNew";
        case Constants.LOST:
            return "InternalLost";
        case Constants.NEWCAR:
            return "NewCar";
        case Constants.OTHER:
            return "InternalStolen";
        case Constants.RENEW:
            return "InternalRenew";
        default:
            return String.Empty;  
     }
}

目前我不得不这样做

private Decimal FindProperty()
{
    switch (Session[Constants.FORMSESSIONKEY].ToString())
    {
        case Constants.NEWAPP:
            return (from p in _costStoreService.List().Where(p => p.DirectorateId == _applicant.DirectorateId)
                    select p.InternalNew).Single() ?? 0.0M;
        case Constants.LOST:
            return (from p in _costStoreService.List().Where(p => p.DirectorateId == _applicant.DirectorateId)
                    select p.InternalLost).Single();
        case Constants.NEWCAR:
            return (from p in _costStoreService.List().Where(p => p.DirectorateId == _applicant.DirectorateId)
                    select p.NewCar).Single();
        case Constants.OTHER:
            return (from p in _costStoreService.List().Where(p => p.DirectorateId == _applicant.DirectorateId)
                    select p.InternalStolen).Single();
        case Constants.RENEW:
            return (from p in _costStoreService.List().Where(p => p.DirectorateId == _applicant.DirectorateId)
                    select p.InternalRenew).Single();
        default:
            return 0.0M;
        }
    }

但它有很多重复的代码,也没有检查包含0值的序列......

1 个答案:

答案 0 :(得分:1)

我假设您的服务返回IQueryable<T>。您可以使用表达式在查询之外定义投影:

    private Expression<Func<CostStore,Decimal>> GetProjection()
    {
        switch (Session[Constants.FORMSESSIONKEY].ToString())
        {
            case Constants.NEWAPP: 
                return c => c.InternalNew;
            case Constants.LOST:
                return c=> c.InternalLost;
            // ... etc, you get the idea
            default:
                return c => 0m; // or some other sensible default
               // break;
        }
    }

如果您的服务返回IEnumerable<T>,请改为使用Func<CostStore,decimal>

你可以像这样使用它:

var projection = GetProjection();
var c = _service.List().Where (condition).Select(projection) 

编辑:把它放在一个控制台应用程序中,学习和学习。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication13
{
class Program
{
    static void Main(string[] args)
    {
        var _service = new Service();

        Func<CostStore, bool> condition = s => s.DirectorateId == 10;
        Func<CostStore, decimal> projection = GetProjection();

        var c = _service.List().Where(condition).Select(projection);
    }

    private static Func<CostStore, decimal> GetProjection()
    {
        return c => c.NewCar;
    }

    class Service
    {
        public IEnumerable<CostStore> List()
        {
            return new List<CostStore>();
        }
    }

    public class CostStore
    {
        public int DirectorateId { get; set; }
        public decimal NewCar { get; set; }
    }
}
}