I have simple class which represents fields in MongoDB document
class Measurement
{
public ObjectId id { get; set; }
public int s { get; set; }
public int[] p { get; set; }
public int dt { get; set; }
public int ml { get; set; }
}
I'm trying to get documents matching my conditions using
var collection = database.GetCollection<Measurement>(mongoCollectionName);
var query = from a in collection.AsQueryable<Measurement>()
where a.dt > 100
select a;
When where condition is removed i do receive all documents but with condition none. Response says there's no matching documents but there are (example dt=1538555)
query looks like this {aggregate([{ "$match" : { "dt" : { "$gt" : 100 } } }])}.
I build my example using response from this thread and mongodb documentation
MongoDB C# Aggregation with LINQ
I would be grateful with solving probably my stupid mistake
i don't use the c# driver directly anymore so my solution is using MongoDAL.
using System;
using System.Linq;
using MongoDAL;
namespace Example
{
class Measurement : Entity
{
public int s { get; set; }
public int[] p { get; set; }
public int dt { get; set; }
public int ml { get; set; }
}
class Program
{
static void Main(string[] args)
{
new DB("measurements");
var measurement1 = new Measurement
{
s = 10,
ml = 20,
dt = 100,
p = new int[] { 1, 2, 3, 4, 5 }
};
var measurement2 = new Measurement
{
s = 11,
ml = 22,
dt = 200,
p = new int[] { 1, 2, 3, 4, 5 }
};
measurement1.Save();
measurement2.Save();
var result = (from m in DB.Collection<Measurement>()
where m.dt > 100
select m).ToArray();
Console.ReadKey();
}
}
}
Related
I'm working on writing an API using .NET 6. I've encountered a "Collection was of a fixed size error" error, which I've never seen before. Looking here on SO I haven't seen anything that addresses this situation. Here's the DbContext class:
using Microsoft.EntityFrameworkCore;
namespace ECommerce.Api.Orders.Db
{
public class OrdersDbContext : DbContext
{
public OrdersDbContext(DbContextOptions dbContextOptions) : base(dbContextOptions)
{
}
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
}
}
Here's the Order class:
namespace ECommerce.Api.Orders.Db
{
/*
* This is the in-memory class for Orders
*/
public class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public DateTime OrderDate { get; set; }
public decimal Total { get; set; }
public ICollection<OrderItem>? Items { get; set; } }
}
And the OrderItem class:
namespace ECommerce.Api.Orders.Db
{
/*
* This is the in-memory class for OrderItems
*/
public class OrderItem
{
public int Id { get; set; }
public int OrderId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
}
}
Now comes the OrdersProvider class. In OrdersProvider I create an orderItems array, an orderItemsTotals array and 3 arrays of type OrderItem which I use to put into new values in the instances I add to the in-memory Orders table. The error comes on the second Add() method in Step 3:
private void SeedData()
{
if (!dbContext.Orders.Any())
{
// Step 1: Start by creating a collection of 3 OrderItems
OrderItem[] orderItems = new OrderItem[]
{
new OrderItem() {Id = 1, OrderId = 1, ProductId = 1, Quantity = 5, UnitPrice = 5.5M},
new OrderItem() {Id = 2, OrderId = 1, ProductId = 2, Quantity = 7, UnitPrice = 13.75M },
new OrderItem() {Id = 3, OrderId = 2, ProductId = 3, Quantity = 10, UnitPrice = 25.99M}
};
// need to get the totals of the values created above, into its own array
decimal[] orderItemTotals = new decimal[3];
for (int i = 0; i < 3; i++)
{
orderItemTotals[i] = orderItems[i].Quantity * orderItems[i].UnitPrice;
}
// Step 2: Need three separate array types to use in the creation of Orders
OrderItem[] orderItems1 = new OrderItem[2]
{
orderItems[0],
orderItems[2]
};
OrderItem[] orderItems2 = new OrderItem[2]
{
orderItems[0],
orderItems[1]
};
OrderItem[] orderItems3 = new OrderItem[1]
{
orderItems[2]
};
// Step 3: Then create a dbContext of Orders the 3 OrderItems above
dbContext.Orders.Add(new Db.Order()
{
Id = 1,
CustomerId = 1,
OrderDate = new DateTime(2022, 1, 17),
Items = orderItems1,
Total = orderItemTotals[0] + orderItemTotals[2]
});
dbContext.Orders.Add(new Db.Order()
{
Id = 2,
CustomerId = 2,
OrderDate = new DateTime(2020, 7, 1),
Items = orderItems2,
Total = orderItemTotals[0] + orderItemTotals[1]
});
dbContext.Orders.Add(new Db.Order()
{
Id = 3,
CustomerId = 3,
OrderDate = new DateTime(2018, 10, 31),
Items = orderItems3,
Total = orderItemTotals[2]
});
dbContext.SaveChanges();
}
}
At this point I don't understand why I'm getting that error when adding the second element after Step 3 in the code immediately above. I would think that Orders is a table; there should be nothing fixed about it. Or it might be related to Items in Order class, but Items is of nullable type of ICollection<OrderItem>. That shouldn't complain about being fixed, either.
So, where am I making my mistake?
I'm developing a project with N-tier architecture. I got errors while generating a new object in the main function.I can not give the features of car1. The entire text is underlined in red and I get these errors "CS1922: Cannot initialize type 'Car' with a collection initializer because it does not implement 'System.Collections.IEnumerable'" and "CS0747: Invalid initializer member declator".
using Business.Concrete;
using System;
using Entities.Concrete;
using DataAccess.Concrete.EntityFramework;
static void Main(string[] args)
{
Car car1 = new Car
{
car1.Id = 4,
car1.BrandId = 1,
car1.ColourId = 2,
car1.ModelYear = 1990,
car1.Name = "King",
car1.DailyPrice = 150,
car1.Description = "Best"
};
CarManager carManager = new CarManager(new EfCarDal());
Console.ReadLine();
}
Entities\Concrete\Car.cs
using Core.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace Entities.Concrete
{
public class Car : IEntity
{
public int Id { get; set; }
public int BrandId { get; set; }
public int ColourId { get; set; }
public string Name { get; set; }
public int ModelYear { get; set; }
public int DailyPrice { get; set; }
public string Description { get; set; }
}
}
You don't need the car1. access when initializing within {} like so:
Car car1 = new Car
{
Id = 4,
BrandId = 1,
ColourId = 2,
ModelYear = 1990,
Name = "King",
DailyPrice = 150,
Description = "Best"
};
Hi can someone assist please,i have a list that contain my promotions codes and in the list i would like to return only promotion codes that appear once i.e dont have duplicates,please see below data from JSON,i would like to return Promotion code A123 and B500 and store them in another list.
[
{
"PromCode": "A123",
"Priority": 1,
"offer": "Win a Free Cap",
"StartDte": "2020-08-11T00:16:23.184Z",
"endDte": "2020-09-10T17:16:23.184Z",
},
{
"PromCode": "A100",
"Priority": 1,
"offer": "Win a perfume",
"StartDte": "2020-08-11T00:16:23.184Z",
"endDte": "2020-09-10T17:16:23.184Z",
},
{
"PromCode": "A100",
"Priority": 2,
"offer": "Win a Phone pouch",
"StartDte": "2020-09-11T00:16:23.184Z",
"endDte": "2020-10-10T17:16:23.184Z",
},
{
"PromCode": "B500",
"Priority": 1,
"offer": "Win a free router",
"StartDte": "2020-08-11T00:16:23.184Z",
"endDte": "2020-09-10T17:16:23.184Z",
},
]
I have a list that contains all this promotion code as seen below
var existingProms = await _Repo.GetAllPromCodes(promCodeList);
i tried to get ones that appear once in the list like this
var appearOnce = existingProms.Count(x => existingBnplIndicators.Contains(x.PromCode)).ToList()<2;
var appearOnce = existingProms.where(x=> x.PromCode.Count()).ToList()<2;
But this did not work,there is 0 results returned,could someone show how to get my two Proms A123,B500 into my appearOnce lis.Thankst
You can use GroupBy to get all the results grouped by PromoCode. Then, filter the results based on the number of items each group has to only show when Count() == 1.
Something like this perhaps,
public class Class1
{
public string PromCode { get; set; }
public int Priority { get; set; }
public string offer { get; set; }
public DateTime StartDte { get; set; }
public DateTime endDte { get; set; }
}
var obj = JsonConvert.DeserializeObject<List<Class1>>(json);
var singlesOnly = obj.GroupBy(x => x.PromCode).Where(y => y.Count() == 1);
You should compare desired objects only by promcode implicitly. Take look how Equals and GetHashCode() works.
using System;
using System.Collections.Generic;
using System.Linq;
namespace test
{
public class TestObj : IEquatable<TestObj>
{
public string Promocode { get; set; }
public int Priority { get; set; }
public string offer { get; set; }
public DateTime StartDate { get; set; }
public DateTime endDate { get; set; }
public override int GetHashCode() => this.Promocode.GetHashCode();
public bool Equals(TestObj other) => Promocode.Equals(other.Promocode);
}
class Program
{
static void Main(string[] args)
{
var a = new TestObj()
{
Promocode = "1",
Priority = 1,
offer = "1",
StartDate = new DateTime(1, 2, 3),
endDate = new DateTime(1, 2, 3)
};
var b = new TestObj()
{
Promocode = "1",
Priority = 1,
offer = "1",
StartDate = new DateTime(1, 2, 3),
endDate = new DateTime(1, 2, 3)
};
var c = new TestObj()
{
Promocode = "2",
Priority = 1,
offer = "1",
StartDate = new DateTime(1, 2, 3),
endDate = new DateTime(1, 2, 3)
};
var list = new List<TestObj>()
{
a,
b,
c
};
var uniqueOnly = list.Distinct();
foreach (var item in uniqueOnly)
{
Console.WriteLine(item.Promocode);
}
}
}
}
First define class items-
public string PromCode { get; set; }
public int Priority { get; set; }
public string offer { get; set; }
public DateTime StartDte { get; set; }
public DateTime endDte { get; set; }
Then take multiple items in list and use distinct() function to remove duplicate values-
static void Main(string[] args)
{
List<TestClass> list = new List<TestClass>()
{
new TestClass(){PromCode="A123",Priority=1,offer="Win a Free
Cap",StartDte=new DateTime(2020-08-11),endDte=new DateTime(2020-09-10)},
new TestClass(){PromCode="A100",Priority=1,offer="Win a
perfume",StartDte=new DateTime(2020-08-11),endDte=new DateTime(2020-09-
10)},
new TestClass(){PromCode="A100",Priority=2,offer="Win a Phone
pouch",StartDte=new DateTime(2020-09-11),endDte=new DateTime(2020-10-10)},
new TestClass(){PromCode="B500",Priority=1,offer="Win a free
router",StartDte=new DateTime(2020-08-11),endDte=new DateTime(2020-09-10)}
};
var finalList = list.Select(b => b.PromCode).Distinct().ToList();
foreach(var item in finalList)
{
Console.WriteLine(item + "");
}
Console.Read();
}
}
I want to filter my query using MongoDb c# driver. I have a query list so I need to filter records if all the list item included in the sub collection of a collection.
public class Hotels
{
[BsonId]
// standard BSonId generated by MongoDb
public ObjectId InternalId { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public List<int> Amenities { get; set; }
}
I have a query parameter "amenities" as string then splitted with respect to ",".
if (!string.IsNullOrEmpty(amenties))
{
var amenityList =Array.ConvertAll<string,int>( amenties.Split(","),int.Parse).ToList();
filter &= Builders<Hotels>.Filter.Where(r => r.Amenities.All(i => amenityList.Contains(i)));
}
var result =_context.GetCollection<Hotels>(typeof(Hotels).Name).Find(filter);
Throws exception : unsupported filter. Thus, how can I fix this query ?
Thanks
your Where expression is wrong. have a look at the last line of the following code for the correct expression.
using MongoDB.Entities;
using System;
using System.Linq;
namespace StackOverflow
{
public class Program
{
public class Hotel : Entity
{
public string Name { get; set; }
public int[] Amenities { get; set; }
}
private static void Main(string[] args)
{
new DB("test");
(new[] {
new Hotel{ Name= "hotel one", Amenities = new[] {1, 3, 5, 7 } },
new Hotel{ Name= "hotel two", Amenities = new[] {2, 4, 6, 8 } }
}).Save();
string amenities = "2,4,6,8";
int[] amenityList = amenities.Split(",").Select(a => Convert.ToInt32(a)).ToArray();
var result = DB.Find<Hotel>()
.Many(h => amenityList.All(a => h.Amenities.Contains(a)));
}
}
}
it generates the following find query:
"command": {
"find": "Hotel",
"filter": {
"Amneties": {
"$all": [
NumberInt("2"),
NumberInt("4"),
NumberInt("6"),
NumberInt("8")
]
}
}
}
Given the classes below, I want to be able to use a List of ids to return designs that have the AttributeId of 1 or 3 in the DesignAttribute table.
public class Design
{
public int DesignId { get; set; }
public string DesignName { get; set; }
public virtual List<DesignAttribute> DesignAttributes { get; set;}
}
public class Attribute
{
public int AttributeId { get; set; }
public string AttributeName { get; set; }
}
public class DesignAttribute
{
public int DesignAttributeId { get; set; }
public virtual Design Design { get; set; }
public virtual Attribute Attribute { get; set; }
}
A design can have 1 or more attributes, for example
Design Table
DesignId DesignName
1 Design A
2 Design B
3 Design C
Attribute Table
AttributeId AttributeName
1 Light
2 Dark
3 Demo
DesignAttribute Table
DesignAttributeId Design_DesignId Attribute_AttributeId
1 1 1 Design A is Light
2 1 3 Design A is also a Demo
3 2 2 Design B is Dark
4 3 1 Design C is Light
I've got the following code
//attributes list = "[1,3] I want any designs that have Light OR Demo attributes"
public List<Design> FilterDesigns(List<string> attributes)
{
//sudo code as i'm not sure how to structure this.
var designs = db.Designs.Where(i => i.DesignAttributes
WHERE DesignAttributes.AttributeId is in the list of attributes passed into the method)
}
So i'd hopefully end up with a list of 2 items containing the designs Design A and Design C, as they both have an ID against the Attribute Id 1 and 3 in the DesignAttribute lookup table.
Try this :
var designs = db.Designs.Where(design =>
design.DesignAttributes.Any(designAttribute =>
attributes.Contains(designAttribute.Attribute.AttributeId)))
.ToList();
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication29
{
class Program
{
static void Main(string[] args)
{
List<Design> designTable = new List<Design>() {
new Design() { DesignId = 1, DesignName = "A"},
new Design() { DesignId = 2, DesignName = "B"},
new Design() { DesignId = 3, DesignName = "C"}
};
List<Attribute> attributeTable = new List<Attribute>() {
new Attribute() { AttributeId = 1, AttributeName = "Light"},
new Attribute() { AttributeId = 2, AttributeName = "Dark"},
new Attribute() { AttributeId = 3, AttributeName = "Demo"}
};
List<DesignAttribute> designAttributeTable = new List<DesignAttribute>() {
new DesignAttribute() { DesignAttributeId = 1, DesignId = 1, AttributeId = 1},
new DesignAttribute() { DesignAttributeId = 2, DesignId = 1, AttributeId = 3},
new DesignAttribute() { DesignAttributeId = 3, DesignId = 2, AttributeId = 2},
new DesignAttribute() { DesignAttributeId = 4, DesignId = 3, AttributeId = 1}
};
var results = (from dattbl in designAttributeTable
join dttbl in designTable on dattbl.DesignId equals dttbl.DesignId
join attbl in attributeTable on dattbl.AttributeId equals attbl.AttributeId
select new { designName = dttbl.DesignName, attributeName = attbl.AttributeName }).ToList();
}
}
public class Design
{
public int DesignId { get; set; }
public string DesignName { get; set; }
public virtual List<DesignAttribute> DesignAttributes { get; set; }
}
public class Attribute
{
public int AttributeId { get; set; }
public string AttributeName { get; set; }
}
public class DesignAttribute
{
public int DesignAttributeId { get; set; }
public int DesignId { get; set; }
public int AttributeId { get; set; }
}
}
You can try to use this query:
var ids = new List<int> { 1, 3 };
var designs = db.DesignAttributes
.Where(m => ids.Contains(m.DesignAttributeId))
.Select(p => p.Design)
.ToList();
It will query DesignAttributes where DesignAttributeId are present in list ids. Than it will select Designs.