Linq查询简化/封装

时间:2016-12-20 18:14:36

标签: c# linq linq-to-sql

我有一个数据库,其中包含所有商店的记录及其开放和关闭时间。目前,我有一个linq查询来为数据库中的每个商店提取这些时间。以下是代码:

StoresDatabaseDataContext db = new StoresDatabaseDataContext();
var serverData = from c in db.Stores
                    where c.storeID == currentStore.id
                    select new
                    {
                        openTime = c.SundayOpen,
                        closeTime = c.SundayOpen < c.SundayClose ? c.SundayClose : c.MondayClose,
                        timeZone = c.TimeZone,
                        hasDaylightSavings = c.DaylightSavings
                    };

switch (weekDay)
{
    case DayOfWeek.Monday:
        serverData= from c in db.Stores
                        where c.storeID == currentStore.id
                        select new
                        {
                            openTime = c.MondayOpen,
                            closeTime = c.MondayOpen < c.MondayClose ? c.MondayClose : c.TuesdayClose,
                            timeZone = c.TimeZone,
                            hasDaylightSavings = c.DaylightSavings
                        };
        break;
    case DayOfWeek.Tuesday:
        serverData = from c in db.Stores
                        where c.storeID == currentStore.id
                        select new
                        {
                            openTime = c.TuesdayOpen,
                            closeTime = c.TuesdayOpen < c.TuesdayClose ? c.TuesdayClose : c.WednesdayClose,
                            timeZone = c.TimeZone,
                            hasDaylightSavings = c.DaylightSavings
                        };
        break;
//...
}

这运行正常,但是有很多重复的代码,我想通过封装或其他方法来减少这种情况。一种简单的方法是降低switch语句的复杂性:

serverData =    from c in db.Accounts
                where c.storeID == currentStore.id
                select new
                {
                    switch (weekDay)
                    {
                        case DayOfWeek.Monday:
                            openTime = c.MondayOpen;
                            closeTime = c.MondayOpen < c.MondayClose ? c.MondayClose : c.TuesdayClose;
                            break;
                        case DayOfWeek.Tuesday:
                            openTime = c.TuesdayOpen;
                            closeTime = c.TuesdayOpen < c.TuesdayClose ? c.TuesdayClose : c.WednesdayClose; 
                            break;
                        //....
                    },
                    timeZone = c.TimeZone,
                    hasDaylightSavings = c.DaylightSavings
                };

但我不确定如何以这种方式提取时间。任何建议都将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:2)

我的建议是将查询返回的内容的创建委托给帮助程序工厂类。然后在投影查询结果时调用该类。

在工厂类中,您可以使用委托来简化对getter的调用(根据DayOfWeek的不同而不同):

static class RecordFactory
{
    private delegate DateTime TimeGetterFunction(Store s);

    static object New(Store store, DayOfWeek weekDay)
    {
        var timeOpen = new Dictionary<DayOfWeek, TimeGetterFunction>();
        timeOpen.Add(DayOfWeek.Monday, (s) => s.mondayOpen);
        timeOpen.Add(DayOfWeek.Tuesday, (s) => s.tuesdayOpen);

        var timeClose = new Dictionary<DayOfWeek, TimeGetterFunction>();
        timeClose.Add(DayOfWeek.Monday, (s) => s.mondayClose);
        timeClose.Add(DayOfWeek.Tuesday, (s) => s.tuesdayClose);

        return new { 
            TimeOpen = timeOpen[weekDay](store), 
            TimeClose = timeClose[weekDay](store) 
            //Add more properties...
        };
    }
}

// in your Linq query...
select RecordFactory.New(DayOfWeek.Monday, s);