C# query basic BSON knowing only key and values using LINQ - c#

I have MongoDB collection from which I would like to query documents knowing only names of the keys.
I cannot use hardcoded base class because amount on keys will change over time in runtime. But as user I will know the names of them.
I tried doing it like that:
var collection = database.GetCollection<BsonDocument>(mongoCollectionName);
List<BsonDocument> list = (from c in collection.AsQueryable<BsonDocument>()
where c.GetElement("serial").Value == 1
select c).ToList();
but with that i get {document}.GetElement("serial").Value is not supported
So is there a way to use linq to query basic BSONs ?
Thanks !

Just make the viewModel same as the properties in MongoDb.
and For getting serial column whose value is 1, just do like this,
public class ViewModel {
.... model Properties goes here
}
var SerialNo = 1;
var collection = mongoDatabase.GetCollection<ViewModel>("name of your collection");
var builder = Builders<ViewModel>.Filter;
builder.Eq(x => x.serial, SerialNo );

Is it necessary to use LINQ? I mean it is not possible for you to do something like this?
var collection = database.GetCollection<BsonDocument>(mongoCollectionName);
List<BsonDocument> list = collection.Find(Builders<BsonDocument>.Filter.Eq("serial", 1)).ToList();
or even convert it to Dictionary.

Related

How to preserve list values after linq operation?

I am querying azure table. After getting the data I am performing linq select operation and getting modified values.
But I want two lists one with old values and other with new values.
var oldUserEntities = userEntities.ToList();
var newUserEntities = userEntities.Select(i => { i.RowKey = dict[i.RowKey]; return i; }).ToList();
After this code if I verify values in oldUserEntites and newUserEntities, both having same modified values.
How to have old list and new list?
That's because the i in your projection is referencing the original item in oldUserEntities, then i.RowKey is modifying the original data.
Try this instead (assuming your entity is named UserEntity):
var oldUserEntities = userEntities.ToList();
var newUserEntities = userEntities.Select(i => new UserEntity
{
RowKey = dict[i.RowKey],
// rest of desired properties ...
}).ToList();
I'm not really sure what you're trying to do here, but this
> i => { i.RowKey = dict[i.RowKey]; return i }
is changing RowKey on every object in the list. The "return i" is then making a list containing the same, now modified, objects.
all this is really doing is
foreach(i in userEntities)
i.RowKey = dict[i.RowKey]
and then making a copy of the list

Retrieve value of field in list of entity objects by its ID field

I have something like:
List<Cat> cats = AnimalEdmContext.Current.Cats.ToList();
Where Cat is a table in my database, with fields CatId and Breed.
How can I access the value of the Breed field that corresponds to a given integer CatId?
You need to query over the database to do that. The following example shows you how to do that.
var theCatId = 1; // Or whatever
var theCatIWant = AnimalEdmContext.Current.Cats.Where(c => c.CatId = theCatId).Single();
var theBreedIs = theCatIWant.Breed;
Doing this you just retrieve from the database the Cats that match your condition. In the other hand, if you do the filtering over the whole list like the one you are getting in your question, you will be retrieving all records from database and then filtering them, which costs more.
The Single LINQ method allows you to specify the condition as well, that the single element should match. I have added the Where method to so it is clearer what we are doing.
Single will throw an exception if no record is found or if more than one are found.
You can use ::
var catBreed = cats.First(x=>x.CatdId == desiredId).Breed;
If you are looking for a specific item, you could do something like:
var cat = AnimalEdmContext.Current.Cats.First(cat => cat.CatId == 1);
var breed = cat.Breed;
This will retrieve the first Cat item in the table that has the ID of 1, in this example.

C# use LINQ to query custom list and return new subset list

I have a list of a custom type called Holdings. I am trying to query the list based on one property of the Holdings object to return a new list of Holdings. The LINQ query below does work correctly but I would like to replace var unitHld with List unitHld but can't get the code to work.
var unitHld = from hld in _holdingList
where hld.FundCode == lookThroList[i].FundCode
select new Holding() { Currency = hld.Currency,
FundCode = lookThroList[i].FundCode,
IdSedol = hld.IdSedol,
Nominal = hld.Nominal * unitWgt,
Price = hld.Price };
This new list is then slightly altered before being added back to the original list (I know the logic sounds strange but please accept this is how it has to be done). However because unitHld is var the line below does not work.
_holdingList.Add(unitHld);
The following call only adds a single item (where the item must be the same type as the list's elements):
_holdingList.Add(unitHld);
But you want to add a range of items, so do it like this:
_holdingList.AddRange(unitHld);
where unitHld is IEnumerable<T> and T is the type of the list's elements.
(This answer assumes that holdingList is of type List<T>, and that T is in fact Holding for your example.)
See List.AddRange() for details.
C# is statically typed.
var is not a type, all it does is a shortcut for in your case typing IEnumerable<Holding>.
If you want the result to be List<Holding> then all you need to do is wrap your query in brackets and put .ToList() at the end.
However, to append this to another list, you don't need to do that. Simply call .AddRange on the other list.
Alternatively, you can use Concat
var bothLists = aList.Concat(anotherList);
I would like to replace var unitHld with List unitHld but can't get the code to work.
You need to call ToList() on the result of the query:
var unitHld = from hld in _holdingList
where hld.FundCode == lookThroList[i].FundCode
select new Holding() { Currency = hld.Currency,
FundCode = lookThroList[i].FundCode,
IdSedol = hld.IdSedol,
Nominal = hld.Nominal * unitWgt,
Price = hld.Price };
List<Holding> unitHldList = unitHld.ToList();
This new list is then slightly altered before being added back to the original list
Once the data is in unitHldList, you can alter it as needed.
the line below does not work. _holdingList.Add(unitHld);
When you add the content of a collection to a List<T>, use AddRange method instead of Add:
_holdingList.AddRange(unitHldList);
Try this:
_holdingList.AddRange(unitHld);

Linq to SQL select multiple columns

I just want to select 2 columns from a MSSQL DB using LINQ.
The SQL should be
select table.col1,table.col2 from table
I tried
IList<string> myResults =
(
from data in dbconn.table
where table.col5 == null
select new {
col1=data.Id.ToString(),
col2=data.col2
}
).Take(20).ToList();
but this didn't work.
It says
cannot convert type list <AnonymousType#1> to Ilist<string>
You are basically trying to fill a list of strings with the entries of a list of anonymous types, that won't work.
Have you tried something like this?:
var list = from data in dbconn.table
where table.col5 == null
select new {
col1=data.Id.ToString(),
col2=data.col2
}
Then you can easily use the entries in a loop for example
foreach(var element in list) {
//...
}
Or like a list
list.Take(20).ToList();
First of all, a list of strings (List<string>) can only have one single string in an element not two (what you are trying to do here) changing the type to var would fix your exception but not sure if that is the solution you want.
var myResults =
(
from data in dbconn.table
where table.col5 == null
select new {
col1=data.Id.ToString(),
col2=data.col2
}
).Take(20).ToList();
You can select multiple fields using linq Select as shown above in various examples this will return as an Anonymous Type. If you want to avoid this anonymous type here is the simple trick.
var items = myResults.Select(f => new [] { f.Col1, f.Col2 }).SelectMany(item => item).Distinct();
I think this solves the problem

Linq query with select needed to get specific properties from a list

I have a Linq query of which contains a List within a list. I thought I only wanted to have First record so I had the select part of my query written like this:
select new
{
EtchVectors = vio.Shapes.FirstOrDefault().Formatted
}).ToList();
This works great, it returns first record and the list that I have aliased "vio" has a list in it ( public List Shapes { get; set; } and Parse contains 2 properties, Formatted and Original. As I am rewriting this it seems I do not have access to "Formatted" if I get rid of FirstOrDefault()
This returns BOTH Formatted and Original obviously
EtchVectors = vio.Shapes
but, I cannot obviously do this:
EtchVectors = vio.Shapes().Formatted ( Shapes cannot be used like a method)
Should I be doing a different method or using a lambda ??
I think you are looking for a projection
EtchVectors = vio.Shapes.Select( s => s.Formatted );

Categories

Resources