How to run complex query with Any() inside Any(). MongoDB Driver C# - c#

I haven't been able to perform a complex query with an Any() inside an Any(), using MongoDB C# Driver..
I have this C# models (equivalent to the mongo database models):
[BsonCollection("alert_evaluations")]
public class AlertEvaluation : Document
{
public ICollection<EvaluationResult> EvaluationResults { get; set; }
public string EvaluationStatus { get; set; }
public DateTime EvaluatedAt { get; set; }
}
public class EvaluationResult
{
public ICollection<EvaluatedLabel> EvaluatedLabels { get; set; }
public double ResultNumber { get; set; }
}
public class EvaluatedLabel
{
public string LabelId { get; set; }
public string Value { get; set; }
}
And I get a list of the next model (as a parameter to filter):
public class EvaluatedLabelFilterDTO
{
public string LabelId { get; set; }
public string Value { get; set; }
}
What I would need to do is to filter AlertEvaluations by getting the ones that have EvaluationResults with EvaluatedLabels that match the same LabelId and Value of the list of EvaluatedLabelFilterDTO objects.
With LinQ I tried something like this:
FilterDefinitionBuilder<AlertEvaluation>.Where(x => x.EvaluationResults.Any(e => e.EvaluatedLabels.Any(z => evaluatedLabelsToFilter.Any(f => f.LabelId == z.LabelId && f.Value == z.Value))));
But of course, this is not supported by mongo..
I'm not really familiar with mongo queries..
Is there any way to do this as a BsonDocument filter query? (Or any other solution).
(The result has to be a FilterDefinition<>, not the list already).
I could really use some help with this. Thanks!

Related

Select a table column from IEnumerable using Linq

Am having my table as below , by the usage of Sqlite :
public class Medication
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string unique_id { get; set; }
public string username { get; set; }
public string insulin_type { get; set; }
public string units { get; set; }
public string status { get; set; }
public string alarm_time { get; set; }
public Medication() { }
}
Now I want to use IEnumerable to get a Column alarm_time List but I don't know how to get it. Below is my code for that:
public IEnumerable<Medication> AllMedicationResults()
{
return (from t in _connection.Table<Medication>()
select t).ToList();
}
How can I include the Column alarm_time in that code above.
In your select request only that property (and change method return type)
public IEnumerable<string> AllMedicationResults()
{
return (from t in _connection.Table<Medication>()
select t.alarm_time).ToList();
}
But IMO it will look cleaner to just use method syntax:
public IEnumerable<string> AllMedicationResults()
{
return _connection.Table<Medication>().Select(t => t.alarm_time).ToList();
}
Notice that as you are returning an IEnumerable<T> you might want to consider removing the ToList() and using the benefits of linq's deffered execution

Mongodb C# filter using LINQ

I have to filter my mongodb collection on the basis of 3 values.
My class structure is
public class Rootobject
{
public object _id { get; set; } //MongoDb uses this field as identity.
public Root root { get; set; }
}
public class Root
{
public Row[] row { get; set; }
}
public class Row
{
public string ID { get; set; }
public string MarketProfileID { get; set; }
public string CodeDetails { get; set; }
public string OfferTypeID { get; set; }
}
I have to apply the filter in mongo db :
var obj = Query.And(
Query<Rootobject>.EQ((c => c.root.row.MarketProfileID, marketProfileID.ToString())
Query<Rootobject>.EQ(c => c.root.row.CodeDetails, code),
Query<Rootobject>.EQ(c => c.root.row.PrivacyLevelID, customerTypeID.ToString())
);
List<Rootobject> obj = objDatabse.GetCollection<Rootobject>("Offer").Find(obj ).ToList();
But it is not compiling.
Please assist
Offer is a mongodb Collection
I recommend to use LINQ syntax here.
Please try this:
IMongoCollection<Rootobject> rootCollection = rootsDatabase.GetCollection<Rootobject>("Offer");
var roots = rootCollection.Find<Rootobject>(r => r.root.row.Any(
row => row.MarketProfileID == "somevalue" &&
row.CodeDetails == "somevalue")).ToList();
Your row class doesn't have PrivacyLevelID, so it would not compile anyways, but I hope you got the idea.

Returning all entries in a C# list matching an int

I have a list that has the following:
class GetMyList
{
public int searchInt { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string Retype { get; set; }
public string Time { get; set; }
public string City { get; set; }
public DateTime dateHere { get; set; }
}
This list could have multiple entries for each int (ie the searchInt 1 could have an entry for 4/11/2017 and another for 4/12/2017).
How do I return ALL of the entries that match the searchInt of 1 in my example above? Preferably so I can just access the dateHere field but it would be nice to know the others, if that matters.
You could simply utilize Linq.
var filter = collection.Where(search => search.searchInt == 1);
The Where would in essence match on a predicate, so in this case all items that evaluate to true in my statement, will be returned.

C# Linq search inside object linked property

i'm trying to do some search inside some attributes of my object set but i'm getting some trouble on the right way to mount my linq query, i have my VT_Video class which has its attributes and some linked objects
public partial class VT_Video
{
public int ID { get; set; }
public string title { get; set; }
public string description { get; set; }
public virtual ICollection<VT_VideoTag> VT_VideoTag { get; set; }
}
public partial class VT_VideoTag
{
public int ID { get; set; }
public int tagID { get; set; }
public int videoID { get; set; }
public virtual VT_Tag VT_Tag { get; set; }
public virtual VT_Video VT_Video { get; set; }
}
public partial class VT_Tag
{
public int ID { get; set; }
public string name { get; set; }
public virtual ICollection<VT_VideoTag> VT_VideoTag { get; set; }
}
What i want to accomplish is search a user given word inside my Video collection by VT_Video.title, VT_Video.description and also by VT_Video.VT_VideoTag.VT_Tag.name, what i managed to do so far is only search the title and description:
var myVideos = db.VT_Video.Include("VT_VideoTag")
.Include("VT_VideoTag.VT_Tag")
.Where(vid =>
vid.descricao.Contains(strBusca) ||
vid.titulo.Contains(strBusca)).ToList();
Now, i know i can do what i want with some foreach and extra code but i wondered if it would be possible to do it using linq and also keep my code clean.
Thanks.
I have not worked with LINQ to SQL much, but it seems like .Any() would satisfy your requirement:
var myVideos = db.VT_Video.Include("VT_VideoTag")
.Include("VT_VideoTag.VT_Tag")
.Where(vid =>
vid.descricao.Contains(strBusca) ||
vid.titulo.Contains(strBusca) ||
vid.VT_VideoTag.Any(tag => tag.name.Contains(strBusca))).ToList();
Notice I added this clause:
vid.VT_VideoTag.Any(tag => tag.name.Contains(strBusca))
Which returns true if any tag in the collection has a name that contains your search string.

Find object with in class using LINQ

I want to return the item that has the profile ID I send. So in order to do this I will need to loop through all of the Items -> WebProproperties -> profile. The Class structure is at the end of the question.
I would rather use LINQ than create a nested foreach. I have been trying to get this to work for more than an hour now. I am stuck.
My first idea was to simply use where. But that doesn't work because you need to have something on the other side that needs to equal.
this.Accounts.items.Where(a => a.webProperties.Where(b => b.profiles.Where(c => c.id == pSearchString)) ).FirstOrDefault();
My second idea was to try using Exists which I don't have much experience with:
Item test = from item in this.Accounts.items.Exists(a => a.webProperties.Exists(b => b.profiles.Exists(c => c.id == pSearchString))) select item;
This doesn't work either:
Could not find an implementation of query pattern for source type 'Bool'
public RootObject Accounts {get; set;}
public class RootObject
{
public string kind { get; set; }
public string username { get; set; }
public int totalResults { get; set; }
public int startIndex { get; set; }
public int itemsPerPage { get; set; }
public List<Item> items { get; set; }
}
public class Profile
{
public string kind { get; set; }
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class WebProperty
{
public string kind { get; set; }
public string id { get; set; }
public string name { get; set; }
public string internalWebPropertyId { get; set; }
public string level { get; set; }
public string websiteUrl { get; set; }
public List<Profile> profiles { get; set; }
}
public class Item
{
public string id { get; set; }
public string kind { get; set; }
public string name { get; set; }
public List<WebProperty> webProperties { get; set; }
}
You can use Any() to determine existence. Also, note that many of the extension methods have overloads which take a predicate, including FirstOrDefault():
this.Accounts.items.FirstOrDefault(a => a.webProperties
.Any(b => b.profiles
.Any(c => c.id == pSearchString)));
You are looking for the .Any() operation I think. This will return true/false for whether there are any items matching your query.
For example:
if (this.Accounts.Items.Any(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)));
EDIT: You have full answer (was posted while I was composing mine) and as pointed out in comments my answer isn't actually returning your found item, just letting you know whether there is one. You can rework the first .Any to be a .FirstOrDefault to get that match.
E.g.
var result = this.Accounts.Items.FirstOrDefault(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)))
You can use the below mentioned code.
var abc = rr.items.Where(p => p.webProperties.Any(c => c.profiles.Any(d => d.id == "1"))).FirstOrDefault();
Just for your reference, your class should look like:
public class RootObject
{
public string kind { get; set; }
public string username { get; set; }
public int totalResults { get; set; }
public int startIndex { get; set; }
public int itemsPerPage { get; set; }
private List<Item> _items=new List<Item>();
public List<Item> items
{
get { return _items; }
set { _items = value; }
}
}

Categories

Resources