如何重构LINQ查询

时间:2015-02-03 21:04:43

标签: c# linq linq-to-entities

我有以下代码:

result = from i in _dbContext.Meetings
         where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && //!i.IsTex &&
         DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
         //where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
         select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
         {
             Name = i.UserInviter.FirstName + " " + i.UserInviter.LastName,
             Company = i.UserInviter.Company,
             Company2 = i.UserInvited.Company,
             MeetingID = i.MeetingID,
             Time = DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value,
             CreatedTime = i.dateCreated,
             Image = i.UserInviter.ProfileImage,
             TableNumber = i.TableNumber,
             Username = i.UserInviter.aspnet_User.UserName,
             Username2 = i.UserInvited.aspnet_User.UserName,
             UsernameInviter = i.UserInviter.aspnet_User.UserName,
             RequestText = i.RequestText,
             NoteInviter = i.NoteInviter,
             ResendInvitationCount = (i.ResendInvitationCount.HasValue) ? i.ResendInvitationCount.Value : 0,
             NoteInvited = i.NoteInvited,
             MeetingType = i.MeetingType.TypeName
         };

我使用了许多具有不同修改的扩展,但每个扩展都具有相同的部分select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()....

result = from i in _dbContext.Meetings
         where i.UserInviterID == CurrentUserID && i.MeetingStatus == null && !i.IsTex && DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
         //where i.UserInviterID == CurrentUserID && i.MeetingStatus == null && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
         select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
         {
             Name = i.UserInvited.FirstName + " " + i.UserInvited.LastName,
             //...
         };


result = from i in _dbContext.Meetings
         where (i.UserInviterID == CurrentUserID) && i.MeetingStatus == true && !i.IsTex && DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
         //where (i.UserInviterID == CurrentUserID) && i.MeetingStatus == true && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
         select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
         {
             Name = i.UserInvited.FirstName + " " + i.UserInvited.LastName,
             //...
         };

我可以将此部分设置为变量以用于所有其他扩展吗?

2 个答案:

答案 0 :(得分:3)

您需要放弃LINQ查询语法,并直接调用Select方法。这应该没什么大不了的。如果这样做,您可以将查询的投影部分存储在单独的变量中。

Expression<Func<Meeting, ITW2012Mobile.Core.DataTable.MeetingModel2Tmp>> projection = i =>
    new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
    {
        Name = i.UserInviter.FirstName + " " + i.UserInviter.LastName,
        Company = i.UserInviter.Company,
        Company2 = i.UserInvited.Company,
        MeetingID = i.MeetingID,
        Time = DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value,
        CreatedTime = i.dateCreated,
        Image = i.UserInviter.ProfileImage,
        TableNumber = i.TableNumber,
        Username = i.UserInviter.aspnet_User.UserName,
        Username2 = i.UserInvited.aspnet_User.UserName,
        UsernameInviter = i.UserInviter.aspnet_User.UserName,
        RequestText = i.RequestText,
        NoteInviter = i.NoteInviter,
        ResendInvitationCount = (i.ResendInvitationCount.HasValue) ? i.ResendInvitationCount.Value : 0,
        NoteInvited = i.NoteInvited,
        MeetingType = i.MeetingType.TypeName
    };

...

result =
   (from i in _dbContext.Meetings
    where i.UserInviterID == CurrentUserID
    && i.MeetingStatus == null
    && !i.IsTex
    && DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
    select i).Select(projection);

这保留了查询服务器端的整个部分,就像你在每个查询中写出来一样。

答案 1 :(得分:-2)

是的,您可以创建一个为您返回ITW2012Mobile.Core.DataTable.MeetingModel2Tmp的方法,并在select中调用该方法。

这样的东西
private ITW2012Mobile.Core.DataTable.MeetingModel2Tmp MethodName(TypeOfI i)
{
   return new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp() {
       //same stuff as in your question's initializer
   };
}

并用

调用它
    result = from i in _dbContext.Meetings
             where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && //!i.IsTex &&
             DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
             //where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
             select MethodName(i);

无论如何,查询将被编译成LINQ扩展方法,.Select()Func<TSource, TResult>作为参数。 Func只是一个委托(方法),它有一个输入参数(类型为TSource)并返回一个TResult对象。

相关问题