1

I am trying to create a generic function to extract the from the query and assign it to the object. Seems the actual linq2sql object is not getting resolved in the generic function to expose the properties within it.

Any help would be appreciated.

        public Production GetData()
        {
            var productionData = new Production();

            var query = (from o in _dbContext.ProductionDatas
                         select new Data<ProductionData>
                         {
                             td = _dbContext.ProductionDatas.Where(x => x.Timestamp <= _reportDate).ToList(),
                             mtd = _dbContext.ProductionDatas.Where(x => x.Timestamp >= _monthStartDate && x.Timestamp <= _reportDate).ToList(),
                             ytd = _dbContext.ProductionDatas.Where(x => x.Timestamp >= _yearStartDate && x.Timestamp <= _reportDate).ToList(),
                             today = _dbContext.ProductionDatas.FirstOrDefault(x => x.Timestamp == _reportDate),
                         }).FirstOrDefault();

            AssignValue(productionData, query);


            return productionData;
        }

        public Production GetDiscardedData()
        {
            var productionData = new Production();

            var query = (from o in _dbContext.ProductionDiscardedDatas
                         select new Data<ProductionData>
                         {
                             td = _dbContext.ProductionDiscardedDatas.Where(x => x.Timestamp <= _reportDate).ToList(),
                             mtd = _dbContext.ProductionDiscardedDatas.Where(x => x.Timestamp >= _monthStartDate && x.Timestamp <= _reportDate).ToList(),
                             ytd = _dbContext.ProductionDiscardedDatas.Where(x => x.Timestamp >= _yearStartDate && x.Timestamp <= _reportDate).ToList(),
                             today = _dbContext.ProductionDiscardedDatas.FirstOrDefault(x => x.Timestamp == _reportDate),
                         }).FirstOrDefault();

            AssignValue(productionData, query);


            return productionData;
        }

        private static void AssignValue<T>(Production productionData, Data<T> query) where T : class 
        {
            if (query != null)
            {
                productionData.Today.Spec1 = query.today.Spec1;
                productionData.Today.Spec2 = query.today.Spec2;
                productionData.Today.Spec3 = query.today.Spec3;

                productionData.MTD.Spec1 = query.mtd.Sum(x => x.Spec1 );
                productionData.MTD.Spec2 = query.mtd.Sum(x => x.Spec2 );
                productionData.MTD.Spec3 = query.mtd.Sum(x => x.Spec3 );

                productionData.YTD.Spec1 = query.ytd.Sum(x => x.Spec1 );
                productionData.YTD.Spec2 = query.ytd.Sum(x => x.Spec2 );
                productionData.YTD.Spec3 = query.ytd.Sum(x => x.Spec3 );

                productionData.TD.Spec1 = query.td.Sum(x => x.Spec1 );
                productionData.TD.Spec2 = query.td.Sum(x => x.Spec2 );
                productionData.TD.Spec3 = query.td.Sum(x => x.Spec3 );
            }
        }

public class Data<T>
{
    public List<T> mtd;
    public List<T> ytd;
    public T today;
    public List<T> td;
}
4

1 回答 1

1

Your AssignValue<T> method is not actually generic - it is specific to ProductionData. IMO you should remove the <T> from this method and replace any remaining T with ProductionData directly.


With the comment:

but I have some other L2S classes with similar property names, that is one of the reason i wanted to seperate the assigning of values. For eg. I have a class - ProductionData, ProductionDataRenewed, ProductionDataDiscarded etc. all of these L2S classes have 3 similar properties Spec1, Spec2, Spec3.

Then the other option here is "interfaces and constraints"; for example:

interface ISpec {
    decimal Spec1 { get; }
    decimal Spec2 { get; }
    decimal Spec3 { get; }
}

With:

public class Data<T> where T : ISpec {...}

And add : ISpec to ProductionData. If ProductionData is a generated file, don't edit the generated file - instead add a separate code file with:

namespace The.Correct.Namespace {
    partial class ProductionData : ISpec {}
}

which will be combined (by the compiler) with the generated file, using implicit interface implementation to pick up the interface members.

And change the Assign<T> constraint from where T : class to where T : class, ISpec and it should work. Obviously, if your data is not decimal change ISpec accordingly.

于 2013-06-27T05:41:21.667 回答