我尝试过使用linq使用Left outer join。每当我更改报告参数时,它都会给我相同的结果。
var _result = (from ls in SessionHandler.CurrentContext.LennoxSurveyResponses
from ml
in SessionHandler.CurrentContext.MailingListEntries
.Where(mle => mle.SurveyCode == ls.SurveyCode).DefaultIfEmpty()
from lists
in SessionHandler.CurrentContext.MailingLists
.Where(m => m.MailingListId == ml.MailingListId).DefaultIfEmpty()
from channel
in SessionHandler.CurrentContext.Channels
.Where(ch => ch.ChannelId == lists.ChannelId).DefaultIfEmpty()
from tmChannelGroup
in SessionHandler.CurrentContext.ChannelGroups
.Where(tcg => tcg.ChannelGroupId == channel.ChannelGroupId).DefaultIfEmpty()
from dmChannelGroup
in SessionHandler.CurrentContext.ChannelGroups
.Where(dcg => dcg.ChannelGroupId == tmChannelGroup.ParentChannelGroupId).DefaultIfEmpty()
from amChannelGroup
in SessionHandler.CurrentContext.ChannelGroups
.Where(acg => acg.ChannelGroupId == dmChannelGroup.ParentChannelGroupId).DefaultIfEmpty()
where (model.ChannelId != 0 && channel.ChannelId == model.ChannelId ||
model.TMId != 0 && channel.ChannelGroupId == model.TMId ||
model.DistrictId != 0 && dmChannelGroup.ChannelGroupId == model.DistrictId ||
model.AreaId != 0 && amChannelGroup.ChannelGroupId == model.AreaId ||
model.AreaId == 0 && amChannelGroup.ChannelGroupId == model.LoggedChannelGroupId ||
model.DistrictId == 0 && dmChannelGroup.ChannelGroupId == model.LoggedChannelGroupId ||
model.TMId == 0 && tmChannelGroup.ChannelGroupId == model.LoggedChannelGroupId ||
model.ChannelId == 0 && tmChannelGroup.ChannelGroupId == model.LoggedChannelGroupId)
&& (ml.EmailDate != null || ml.LetterDate != null || ml.EmailBounce == null)
select ls).ToList();
我有这个LINQ查询,它根据模型值重复(排序)。我怎么能缩短这个查询..如果我可以使用一个var对象而不是使用一堆不同的参数......如果你看到这个代码重复了。
if (model.ChannelId != 0)
{
var _result =
(from ls in SessionHandler.CurrentContext.LennoxSurveyResponses
join ml in SessionHandler.CurrentContext.MailingListEntries on ls.SurveyCode equals ml.SurveyCode
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
where ch.ChannelId == model.ChannelId
&& ml.EmailBounce == null || ml.EmailBounce.Equals(false)
select ls).ToList();
var _SentSurveys =
(from ml in SessionHandler.CurrentContext.MailingListEntries
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
where ch.ChannelId == model.ChannelId
&& (ml.EmailDate != null || ml.LetterDate != null || ml.EmailBounce == null)
select ml).ToList();
model.SentSurveys = _SentSurveys.Count() > 0 ? _SentSurveys.Count() : 0;
model.CompletedSurveys = _result.Count() > 0 ? _result.Count() : 0;
model.PercentageComplete = model.SentSurveys != 0 ? model.CompletedSurveys / model.SentSurveys : 0;
//model.Referring = _result.Average(m => Convert.ToInt32(m.Question1Answer));
model.Referring = Math.Round(_result.Select(m => string.IsNullOrEmpty(m.Question1Answer) ? 0 : Double.Parse(m.Question1Answer)).Average());
model.ServicePerformance = Math.Round(_result.Select(m => string.IsNullOrEmpty(m.Question2Answer) ? 0 : Double.Parse(m.Question2Answer)).Average());
model.InstallPerformance = Math.Round(_result.Select(m => string.IsNullOrEmpty(m.Question3Answer) ? 0 : Double.Parse(m.Question3Answer)).Average());
model.ReferringLennox = Math.Round(_result.Select(m => string.IsNullOrEmpty(m.Question4Answer) ? 0 : Double.Parse(m.Question4Answer)).Average());
}
else if (model.TMId != 0)
{
var _result =
(from ls in SessionHandler.CurrentContext.LennoxSurveyResponses
join ml in SessionHandler.CurrentContext.MailingListEntries on ls.SurveyCode equals ml.SurveyCode
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
where ch.ChannelGroupId == model.TMId
select ls).ToList();
var _SentSurveys =
(from ml in SessionHandler.CurrentContext.MailingListEntries
join m in SessionHandler.CurrentContext.MailingLists on ml.MailingListId equals m.MailingListId
join ch in SessionHandler.CurrentContext.Channels on m.ChannelId equals ch.ChannelId
where ch.ChannelGroupId == model.TMId
&& (ml.EmailDate != null || ml.LetterDate != null || ml.EmailBounce == null)
select ml).ToList();
model.SentSurveys = _SentSurveys.Count() > 0 ? _SentSurveys.Count() : 0;
model.CompletedSurveys = _result.Count() > 0 ? _result.Count() : 0;
model.PercentageComplete = model.SentSurveys != 0 ? model.CompletedSurveys / model.SentSurveys : 0;
model.Referring = _result.Select(m => string.IsNullOrEmpty(m.Question1Answer) ? 0 : Double.Parse(m.Question1Answer)).Average();
model.ServicePerformance = _result.Select(m => string.IsNullOrEmpty(m.Question2Answer) ? 0 : Double.Parse(m.Question2Answer)).Average();
model.InstallPerformance = _result.Select(m => string.IsNullOrEmpty(m.Question3Answer) ? 0 : Double.Parse(m.Question3Answer)).Average();
model.ReferringLennox = _result.Select(m => string.IsNullOrEmpty(m.Question4Answer) ? 0 : Double.Parse(m.Question4Answer)).Average();
}
并且还有5个额外的模型参数,并且对于每个参数,都会创建一个新的var _result和_SentSurveys。我只想简化此代码。
答案 0 :(得分:0)
我认为首先重构这一点可以使编写这些查询变得更加有益。如果这不是一个选项,您可以使用一些CompiledQueries来减少重复的大查询。但这样做并不能使其在效率方面“简化”,只是让你的代码更加清晰。此外,在这两种情况下,您的后处理看起来几乎与许多不必要的检查相同。无需重复常见的事情。通过一些重构,你可能会做这样的事情:
// need to set up the compiled queries first
static readonly Func<MyDataContextType,
MyModelType,
Func<MyDataContextType, MailingListEntry, MailingList, Channel, MyModelType, bool>,
IQueryable<LennoxSurveyResponse>>
GetResult = CompiledQuery.Compile(
(MyDataContextType ctx, MyModelType mod,
Func<MyDataContextType, MailingListEntry, MailingList, Channel, MyModelType, bool> pred) =>
from lsr in ctx.LennoxSurveyResponses
join mle in ctx.MailingListEntries on lsr.SurveyCode equals mle.SurveyCode
join ml in ctx.MailingLists on mle.MailingListId equals ml.MailingListId
join ch in ctx.Channels on ml.ChannelId equals ch.ChannelId
where pred(ctx, mod, mle, ml, ch)
select lsr);
static readonly Func<MyDataContextType, MyModelType, IQueryable<MailingListEntry>>
GetSentSurveys = CompiledQuery.Compile(
(MyDataContextType ctx, MyModelType mod) =>
from mle in ctx.MailingListEntries
join ml in ctx.MailingLists on mle.MailingListId equals ml.MailingListId
join ch in ctx.Channels on ml.ChannelId equals ch.ChannelId
where ch.ChannelId == mod.ChannelId
&& (mle.EmailDate != null || mle.LetterDate != null || mle.EmailBounce == null)
select mle);
static readonly Func<MyDataContextType, MyModelType, MailingListEntry, MailingList, Channel, bool>
ChannelPredicate = CompiledQuery.Compile(
(MyDataContextType ctx, MyModelType mod,
MailingListEntry mle, MailingList ml, Channel ch) =>
ch.ChannelId == mod.ChannelId && ml.EmailBounce == null || !ml.EmailBounce.Value);
static readonly Func<MyDataContextType, MyModelType, MailingListEntry, MailingList, Channel, bool>
TMPredicate = CompiledQuery.Compile(
(MyDataContextType ctx, MyModelType mod,
MailingListEntry mle, MailingList ml, Channel ch) =>
ch.ChannelGroupId == mod.TMId);
static void UpdateModel(MyModelType model)
{
if (model.ChannelId == 0 && model.TMId == 0) return;
var currentContext = SessionHandler.CurrentContext;
var predicate = (model.ChannelId != 0) ? ChannelPredicate : TMPredicate;
var results = GetResults(currentContext, model, predicate).ToList();
var sentSurveys = GetSentSurveys(currentContext, model).ToList();
model.SentSurveys = sentSurveys.Count();
model.CompletedSurveys = results.Count();
model.PercentageComplete = model.SentSurveys != 0 ? model.CompletedSurveys / model.SentSurveys : 0;
model.Referring = _result.Average(m => string.IsNullOrEmpty(m.Question1Answer) ? 0 : Double.Parse(m.Question1Answer));
model.ServicePerformance = _result.Average(m => string.IsNullOrEmpty(m.Question2Answer) ? 0 : Double.Parse(m.Question2Answer));
model.InstallPerformance = _result.Average(m => string.IsNullOrEmpty(m.Question3Answer) ? 0 : Double.Parse(m.Question3Answer));
model.ReferringLennox = _result.Average(m => string.IsNullOrEmpty(m.Question4Answer) ? 0 : Double.Parse(m.Question4Answer));
if (model.ChannelId != 0)
{
// should be rounded
model.Referring = Math.Round(model.Referring);
model.ServicePerformance = Math.Round(model.ServicePerformance);
model.InstallPerformance = Math.Round(model.InstallPerformance);
model.ReferringLennox = Math.Round(model.ReferringLennox);
}
}