0

I've been searching Stackoverflow for the best solution to the problem to this problem:

"The specified type member 'Income' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

I want to avoid copying the whole data set into memory to manipulate it. The code I use right now looks like this, where I want to avoid using AsEnumerable (copying it to local memory).

from refs in entities.ReferralSet 
    where refs.ReferralSince >= fromDate 
    && (refs.ReferralTill ?? DateTime.Today) <= toDate 
    select refs).AsEnumerable().Sum(o => o.Income

The Income code used:

    public double Income
    {
    get
    {
        MembershipType type = /* bla bla bla */
        return Click.Count * CalculateBAL.ReferralEarningClick(type);
    }
}

I know that I can't use properties that are not mapped to a database columns. So what is the best way to work around this problem without copying the whole dataset into memory?

Feel free to ask if I'm missing any information or you need further explanation.

Thanks in advance

4

1 回答 1

0

If you don't want to load the entities into memory and if you can't reproduce the logic of your Income property in SQL to create a calculated - and then mapped - database column, there isn't much you can do. The only option I would see is reducing the amount of loaded data as much as possible to the minimum that is required to perform the calculation - for example by creating a helper property ...

public class IncomeCalculationData
{
    public int X { get; set; }
    public double Y { get; set; }
    //...
}

... using a projection that only loads those required properties instead of full entities ...

var incomeCalculationDataList =
    from refs in entities.ReferralSet 
    where refs.ReferralSince >= fromDate 
        && (refs.ReferralTill ?? DateTime.Today) <= toDate 
    select new IncomeCalculationData { X = refs.X, Y = refs.Y, /* ... */ };

... and a "calculator class" and method (maybe CalculateBAL can serve this purpose):

public double CalculateIncomeSum(IEnumerable<IncomeCalculationData> data)
{
    return data.Sum(d => { ... }); // your logic based on d.X and d.Y, etc.
}

To be called like:

var incomeSum = CalculateBAL.CalculateIncomeSum(incomeCalculationDataList);

You could consider to remove the Income property from your entity altogether and also supply a logic in the calculator class to calculate the income for a single entity. Having such a dependency on a calculation strategy inside an entity looks like a violation of the Single Responsibility Principle to me.

于 2013-07-12T21:58:14.940 回答