Jeremy Miller Jeremy Miller - 1 month ago 12
C# Question

C# linq finding all string values in a list there match in mongodb

My question might not be specific for MongoDb , even though I am using it.

I want to find all records that are contained in my List

Previously I could search with finding OrderNumber

Collection.Find

an incoming parameter of a
string orderNumber


Thus a method collection.find looked like this:

IEnumerable<Activity> activity = Collection.Find<Activity>(o => o.OrderNumber == orderNumber).ToList();


However, now i want to find List

So do I NEED to modify this statement to be a LOOP to find, or can this be modified to
Find
all the records in the List ?

public static IEnumerable<Activity> GetActivitiesByOrderNumber(List<OrderStuff> orderNumber)
{

IEnumerable<Activity> activity = Collection.Find<Activity>(o => o.OrderNumber == orderNumber).ToList();
return activity;
}


Update

Error CS1503 Argument 1: cannot convert from 'JobManager.Models.Activity' to 'JobManager.Controllers.APIs.OrderStuff'


public static IEnumerable<Activity> GetActivitiesByOrderNumber(List<OrderStuff> orderNumber)
{
IEnumerable<Activity> activity = Collection.Find<Activity>(o => orderNumber.Contains(o)).ToList();
return activity;
}


Activity class

public class Activity
{

[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public DateTime? CreatedDate { get; set; }
public int CreatedById { get; set; }
public string CreatedByName { get; set; }

// ..... etc..
}


OrderStuff class

public class OrderStuff
{
public string id { get; set; }
}

Answer

Check out the following working version, I have taken some liberty to change the object names for correct representation of collection.

public static IEnumerable<Activity> GetActivitiesByOrderNumber(List<OrderStuff> orderNumbers)
{
   List<string> OrderStuffIds = orderNumbers.Select(o => o.Id);

    IEnumerable<Activity> activities = Collection.Where(a => OrderStuffIds.Contains(a.Id)).ToList();
    return activity;
}

Explanation:

Why the original code did not work ?

You are comparing the OrderStuff with Activity, when there's no apparent relation between the two, mostly you need to compare using the Id field

Modifications required

  • Fetch the Id list from the OrderStuff List
  • Use the same for comparison, when fetching the Activity list, by comparing Ids

Further Issues:

  • Even the current solution is a O(N^2) implementation
  • Can be further improved by transforming List<OrderStuff> to Hashset<OrderStuff>, which will do a binary search in O(LogN) time instead of O(N)
  • Something like:

    HashSet<OrderStuff> orderNumberHashSet = new HashSet<OrderStuff>(orderNumbers);