I have this Report model:
public class Report
{
[Key]
public int Id { get; set; }
public string ReporterId { get; set; }
[ForeignKey("ReporterId")]
public virtual ApplicationUser Reporter { get; set; }
public int ProductId { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product { get; set; }
public ReportType ReportType { get; set; }
}
Now, I want to return a List<Report> ordered by the most repeated element based on ProductId to the least repeated element.
Is there any way on how to do this with linq?
Try this:
var newList = List.GroupBy(p=> p.ProductId )
.OrderByDescending(x=> x.Count())
.SelectMany(x=> x).ToList();
Related
My scenario: Users will be able to create lists and add items to these lists. What I want to do is to find the items in the lists created by the users at most.
Item Entity
public class Item:BaseEntity
{
public string Name { get; set; }
public decimal Price { get; set; }
public decimal DiscountedPrice{ get; set; }
public virtual ICollection<ItemList> ItemLists { get; set; }
}
Item List Entity
public class ItemList:BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public int UserId { get; set; }
public ICollection<Item> Items { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
}
User Entity
public class User:BaseEntity
{
public string Name { get; set; }
public string Surname { get; set; }
public string Gsm { get; set; }
public string Email { get; set; }
public virtual ICollection<ItemList> ItemLists{ get; set; }
}
my DTO
public class TopItemsForUsers
{
[BsonRepresentation(BsonType.ObjectId)]
[BsonId]
public string ItemId { get; set; }
public string UserId { get; set; }
public int Quantity { get; set; }
}
My Item repository
var query = _context.Items.Include(l => l.ItemLists)
.GroupBy(g => g.ItemLists)
.Select(z => new TopItemsInLists { ItemId = z.Key.ToString(), Quantity = z.Count() })
.OrderByDescending(z => z.Quantity)
.Take(10);
I want to get products that are very present in users' lists
Where am I doing wrong? If anyone has any other suggestions
Try this query. I hope I understand question correctly.
var query =
from u in _context.Users
from il in u.ItemLists
from i in il.Items
group i by new { UserId = u.Id, ItemId = i.Id } into g
select new TopItemsInLists
{
UserId = g.Key.UserId.ToString(),
ItemId = g.Key.ItemId.ToString(),
Quantity = g.Count()
};
query = query
.OrderByDescending(z => z.Quantity)
.Take(10);
I have a product that have list of price, Can i order by price?
public class Product
{
public int Id { get; set; }
public string Title { get; set; }
public IList<ProductPrice> ProductPrices{ get; set; }
}
public class ProductPrice
{
public int Id { get; set; }
public int Degree{ get; set; }
public int Price{ get; set; }
}
I use this code.but don't ordered
_db.Products.Select(m=>m.ProductPrices.OrderBy(o=>o.Price))
You don't need Select, juste call OrderBy and Max directly
var listSorted = _db.Products.OrderBy(p => p.ProductPrices.Max(pp => pp.Price))
If you want to order products by the maximum product price then do this:
_db.Products.OrderBy(p => p.ProductPrices.Max(pp => pp.Price))
Currently I'm working with WebApi and Entity Framework, So I have 3 entities: Products, Categories and ProductCategory; their relationships are:
My problem is that Category entity has a Category Parent property, so it's recursive, my Category Controller looks like this:
public async Task<IHttpActionResult> GetCategory()
{
var category = await db.Category.Select(x=>new {
x.categoryDesc,
x.CategoryId,
x.categoryImage,
x.categoryName,
x.categoryParent
}).ToListAsync();
return Ok(category);
}
I'm returning an anonymous object, the propierty categoryParent its the same object as category so its recursive; when I fill the database with mock data in the Category table and call the get method, everything runs OK because I dont have any data en ProductCategory, but when I fill it(the ProductCategory table) the program crashes.
MY entity classes are:
public class Category {
public int CategoryId { set; get; }
public string categoryName { set; get; }
public string categoryDesc { set; get; }
public string categoryImage { set; get; }
public int? categoryParentId { set; get; }
public virtual ICollection<ProductCategory> ProductCategories { set; get; }
public virtual Category categoryParent { set; get; }
}
public class Product{
public int ProductId { set; get; }
public string productName { set; get; }
public string productDesc { set; get; }
public double productPrice { set; get; }
public string productUrl { set; get; }
public DateTime productPublishDate { set; get; }
public DateTime productModifyDate { set; get; }
public bool productStatus { set; get; }
public int productStock { set; get; }
public virtual ICollection<ProductCategory> ProductCategories { set; get; }
}
public class ProductCategory : IProductCategory {
[Required]
[Key]
[ForeignKey("Category")]
[Column(Order = 1)]
public int CategoryId { set; get; }
[Required]
[Key]
[ForeignKey("Product")]
[Column(Order = 2)]
public int ProductId { set; get; }
public virtual Product Product { set; get; }
public virtual Category Category { set; get; }
}
Can you help me to fix it?, So when I return categoryParent return it recursively, Thanks
I'm guessing you might have better luck if you explicitly state how you want the information organized, and remove the virtual property
IQueryable<Category> category = db.Category;
var result = category.Where(w => w.categoryParentId != null)
.Join(category,
child => (int)child.categoryParentId,
parent => parent.CategoryId,
(child, parent) => new {
child.categoryDesc,
child.CategoryId,
child.categoryImage,
child.categoryName,
parent
}
);
return Ok(await result.ToListAsync());
That should get you the same result as your query above, then you could remove:
public virtual Category categoryParent { set; get; }
Thank you very much but I found the solution: https://practiceaspnet.wordpress.com/2015/11/09/many-to-many-relationships-with-additional-fields/
I used fluent API to resolve the navigation recursive problem I had:
modelBuilder.Entity<Category>()
.HasMany(x => x.ProductCategories)
.WithRequired(x => x.Category)
.HasForeignKey(x=>x.CategoryId);
modelBuilder.Entity<Product>()
.HasMany(x => x.ProductCategories)
.WithRequired(x => x.Product)
.HasForeignKey(x => x.ProductId);
Basically the WithRequired method prevents a navigation property on the other side of the relationship so it stops the recursion
I am having a problem understanding how Linq and EF are working to return data. I have three simple classes
Products,
Materials,
Documents
Products are made up of materials and materials have documents. When I load a product, I want to return all the documents for the materials that product is made up from.
Here are my classes:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
...
public ICollection<ProductMaterials> ProductMaterial { get; set; }
}
public class ProductMaterials
{
public int Id { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
public int MaterialId { get; set; }
public Materials Material { get; set; }
...
}
public class Document
{
public int Id { get; set; }
public string Name { get; set; }
...
public ICollection<MaterialDocument> MaterialDocument { get; set; }
}
public class MaterialDocument
{
public int Id { get; set; }
public int MaterialId { get; set; }
public Materials Material { get; set; }
public int DocumentId { get; set; }
public Document Document { get; set; }
}
I am not having any issues when loading a material and its related documents. I use this query:
var materialDocuments = db.MaterialDocuments
.Include("Document")
.Where(i => i.MaterialId == id)
.ToList();
How can I load Product with related Materials and the Material's documents? Do I need additional Navigation properties on the MaterialDocument class pointing back to ProductMaterials?
To return all of the Document records for a specific Product that you're loading (given an ID we'll call myProductID), just do the following:
var product = db.Products.Find(myProductID); //The product that you're loading
var documents = product.ProductMaterials.SelectMany(pm =>
pm.Material.SelectMany(mat =>
mat.MaterialDocuments.Select(matdoc => matdoc.Document)));
Below is a POCO class i set up with Entity Framework Code first. How can i Query my database so that I can return all brands of a specific category?
Example: You have a list of categories and you click on one. It shows all brands of products available under that category.
I don't know if my classes are set up correctly to do this.
public class Product
{
[Key,ScaffoldColumn(false)]
public int ProductID { get; set; }
public string ProductName { get; set; }
public int? CategoryID { get; set; }
public virtual Category Category { get; set; }
public int? BrandID { get; set; }
public virtual Brand Brand { get; set; }
}
public class Brand
{
[ScaffoldColumn(false)]
public int BrandID { get; set; }
public string BrandName { get; set; }
}
public class Category
{
[ScaffoldColumn(false)]
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
What about
context.Products.
Where(p => p.Category.CategoryID == categoryToFind).Select(p => p.Brand);
or
var brands = context.Products.
Where(p => p.Category.CategoryID == categoryToFind).
Select(p => p.Brand.BrandName).Distinct().ToList();
if you just need brand names.