Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to combine a multi-part LINQ to Entities query
    primarykey
    data
    text
    <p>I posted this code snippet over at Stack Exchange's <a href="http://codereview.stackexchange.com">Code Review</a> (beta) in order to obtain some feedback on how best to refactor a multi-part <code>LINQ</code> query.</p> <p>Being relatively new to <code>LINQ</code>, I'm not really sure where to begin with this query.</p> <p>If anybody could give me any advice on combining a few of the LINQ queries within the method, I'd appreciate it; especially the <strong><em>'exclude'</em></strong> IQueryable collections into the main query (see comments).</p> <p>The query is not particularly performant at the moment and any advice you could give in order to improve its performance from a code perspective would be appreciated. </p> <p>The comments received on Code Review were more architectural, however I'm not currently in a position where I can move anything to the database at this time.</p> <p>I appreciate it's a large method, but I've posted the whole lot to give context.</p> <p>Thanks in advance for any advice you're able to give.</p> <h1>The Method</h1> <pre><code> /// Get templates by username and company public List&lt;BrowsingSessionItemModel&gt; GetItemBrowsingSessionItems( int companyId, string userName, Boolean hidePendingDeletions, Boolean hideWithAppointmentsPending, Boolean hideWithCallBacksPending, int viewMode, string searchString, List&lt;int?&gt; requiredStatuses, List&lt;int?&gt; requiredSources, string OrderBy, BrowsingSessionLeadCustomField fieldFilter) { try { IQueryable&lt;Lead&gt; exclude1; IQueryable&lt;Lead&gt; exclude2; IQueryable&lt;Lead&gt; exclude3; //To prepare call backs pending if (hideWithCallBacksPending == true) { exclude1 = (from l1 in db.Leads where (l1.Company_ID == companyId) from l2 // Hiding Pending Call Backs in db.Tasks .Where(o =&gt; (o.IsCompleted ?? false == false) &amp;&amp; (o.TaskType_ID == (int)RecordEnums.TaskType.PhoneCall) &amp;&amp; (o.Type_ID == (int)RecordEnums.RecordType.Lead) &amp;&amp; (o.Item_ID == l1.Lead_ID) &amp;&amp; (o.Due_Date &gt; EntityFunctions.AddDays(DateTime.Now, -1)) ) select l1); } else { exclude1 = (from l1 in db.Leads where (0 == 1) select l1); } //To prepare appointments backs pending if (hideWithAppointmentsPending == true) { exclude2 = (from a1 in db.Leads where (a1.Company_ID == companyId) from a2 // Hiding Pending Appointments in db.Tasks .Where(o =&gt; (o.IsCompleted ?? false == false) &amp;&amp; (o.TaskType_ID == (int)RecordEnums.TaskType.Appointment) &amp;&amp; (o.Type_ID == (int)RecordEnums.RecordType.Lead) &amp;&amp; (o.Item_ID == a1.Lead_ID) &amp;&amp; (o.Due_Date &gt; EntityFunctions.AddDays(DateTime.Now, -1)) ) select a1); } else { exclude2 = (from a1 in db.Leads where (0 == 1) select a1); } //To prepare deletions if (hidePendingDeletions == true) { exclude3 = (from d1 in db.Leads where (d1.Company_ID == companyId) from d2 // Hiding Pending Deletions in db.LeadDeletions .Where(o =&gt; (o.LeadId == d1.Lead_ID)) select d1); } else { exclude3 = (from d1 in db.Leads where (0 == 1) select d1); } // MAIN QUERY &lt;-- IQueryable&lt;Lead&gt; list = (from t1 in db.Leads from t2 in db.LeadSubOwners .Where(o =&gt; t1.Lead_ID == o.LeadId &amp;&amp; o.Expiry &gt;= DateTime.Now) .DefaultIfEmpty() where (t1.Company_ID == companyId) where ((t2.Username == userName) &amp;&amp; (viewMode == 1)) || ((t1.Owner == userName) &amp;&amp; (viewMode == 1)) || ((viewMode == 2)) // Either owned by the user or mode 2 (view all) select t1).Except(exclude1).Except(exclude2).Except(exclude3); // Filter sources and statuses seperately if (requiredStatuses.Count &gt; 0) { list = (from t1 in list where (requiredStatuses.Contains(t1.LeadStatus_ID)) select t1); } if (requiredSources.Count &gt; 0) { list = (from t1 in list where (requiredSources.Contains(t1.LeadSource_ID)) select t1); } // Do custom field filter here if (fieldFilter != null) { string stringIntegerValue = Convert.ToString(fieldFilter.IntegerValue); switch (fieldFilter.FieldTypeId) { case 1: list = (from t1 in list from t2 in db.CompanyLeadCustomFieldValues .Where(o =&gt; t1.Lead_ID == o.Lead_ID &amp;&amp; fieldFilter.TextValue == o.LeadCustomFieldValue_Value) select t1); break; case 2: list = (from t1 in list from t2 in db.CompanyLeadCustomFieldValues .Where(o =&gt; t1.Lead_ID == o.Lead_ID &amp;&amp; stringIntegerValue == o.LeadCustomFieldValue_Value) select t1); break; default: break; } } List&lt;Lead&gt; itemsSorted; // Sort here if (!String.IsNullOrEmpty(OrderBy)) { itemsSorted = list.OrderBy(OrderBy).ToList(); } else { itemsSorted = list.ToList(); } var items = itemsSorted.Select((x, index) =&gt; new BrowsingSessionItemModel { Id = x.Lead_ID, Index = index + 1 }); return items.ToList(); } catch (Exception ex) { logger.Info(ex.Message.ToString()); return new List&lt;BrowsingSessionItemModel&gt;(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload