0

I am very new with C# and need some help. I am working on someone elses code and they are pulling data from a Model. I am trying to join two tables and need to use Include but the error is '==' cannot be applied to Guid and IQueryable. Could someone help with this please. Thanks in advance!

enter image description here

Yes, I am.

SGekko
  • 335
  • 1
  • 19
  • what are you trying to do in .Select part of the linq query? – Derviş Kayımbaşıoğlu Jan 28 '19 at 21:17
  • You would want `itemIds.Contains(mi.Id)` but that wouldn't be right within the `.Select`. `.Select` is for selecting the fields you want to return. – webnoob Jan 28 '19 at 21:19
  • I want to return a field named ParentId to know if it is empty or not. That's all but I need both tables linked to get that answer. – SGekko Jan 28 '19 at 21:23
  • Possible duplicate of [Operator '==' cannot be applied to operands of type 'System.Guid' and 'string' in linq to entity](https://stackoverflow.com/questions/8009041/operator-cannot-be-applied-to-operands-of-type-system-guid-and-string-i) – Polynomial Proton Jan 28 '19 at 21:28

1 Answers1

3

.Where() represents your filter. .Select() represents what you want back. If you just want the entities back you don't need a .Select().

If you have an association between menu items and MenuItemProgramData, for example, a MenuItem holds a reference to a MenuItemProgramData then you don't even need the first ID select statement:

return context.DbMenuItems
  .Where(x => x.MenItemsProgramData.Plu == plu);

Note: If your context defines DbSet<T> for your various top level entities, you can just use context.Ts rather than .GetItems<T>.

If the relationship exists then this is the preferred approach. Let SQL do the work. The consumer of your method can further .Select() the applicable data, sort it, paginate it, and even append .Include() if you do want to interact with the entire entity graph.

If you don't have a relationship between the menu item and that program data, and know that the # of item IDs from the first query will remain relatively small (say, sub-100) then:

var itemIds = context.DbMenuItemProgramDatas
  .Where(x => x.Plu == plu)
  .Select(x => x.MenuItemId)
  .ToList();

Without the .ToList() you are dealing with an IQueryable which EF would potentially still attempt to translate to SQL statements when later consumed. By using .ToList() it will execute the SQL and populate a List<int>. (Assuming the menu item ID is an int)

To get the IQueryable menu item data rows:

return context.DbMenuItems
  .Where(x => itemIds.Contains(x.Id));

And that is it.

Edit: Based on the comment "I want to return a field named ParentId to know if it is empty or not. That's all but I need both tables linked to get that answer."

Additionally, looking back at the original code, the naming of the method is a bit misleading. GetItemProgramDataForSubItems implies returning MenuItemsProgramData rather than MenuItems... However, if ParentId is a property of MenuItem, then the caller of this method can use:

var hasParentId = context.GetItemProgramDataForSubItems(plu)
  .Any(x => x.ParentId.HasValue);

If the ParentId is on the MenuItemsProgramData:

var hasParentId = context.GetItemProgramDataForSubItems(plu)
 .Any(x => x.MenuItemsProgramData.ParentId.HasValue);

Beyond that, you may want to elaborate on what your entities and relationships look like, and what exactly you aim to accomplish from your method or business logic.

Steve Py
  • 26,149
  • 3
  • 25
  • 43
  • Thank you for your in depth explanation. It is tough when you are trying to learn a new language with no one really to ask. Thanks for your help! – SGekko Jan 28 '19 at 22:47