开发者

Selecting a property based on Name in Linq projection

I have a class say

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; }        
}

and in my controller i want to find out say

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

(etc) property based on a session variable like so in the function below, how can I do this in linq statement...any ideas (_service.List() lists the IEnumerable of the class CostStore

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;  
     }
}

Currently I am having to do this

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.DirectorateI开发者_JS百科d)
                    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;
        }
    }

but its a lot of duplicate code, also no check for sequence containing 0 values...


I'm assuming your service returns IQueryable<T>. You can use an Expression to define projection outside of your query:

    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;
        }
    }

If your service returns IEnumerable<T>, use Func<CostStore,decimal> instead.

You can use it like this:

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

EDIT: put this in a console application, study and learn.

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; }
    }
}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜