Linq query for complicated model - c#

I can't seem to find out the query for a complicated model I'm using. The model looks like this:
public class Stash
{
public int StashId { get; set; }
public int LocationId { get; set; }
public Location Location { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
public int Amount { get; set; }
}
A product can have several locations and now I want to get all the locations that are connected to a product.

var stashes = new List<Stash>();
int productID = [your id];
var result = stashes.Where(stash => stash.ProductId == productID).Select(stash => stash.Location);
If you need the result to be a List add .ToList() at the end.

you can use
Include to load reference of other entity
var result=context.entity.Include(c=>c.product)
.where(c=>c.product.productId==productid)

Related

EF Core query not including empty results

I'm fairly new to EF Core, so please forgive me if I'm missing something easy here or went about this the wrong way. I have the following models (I have removed irrelevant relationships / data for brevity):
public class SaleOrder
{
public int SaleOrderId { get; set; }
public ICollection<SaleOrderRule> Rules { get; set; }
public ICollection<Carton> ScannedCartons { get; set; }
}
public class SaleOrderRule
{
public int SaleOrderRuleId { get; set; }
public int SaleOrderId { get; set; }
public SaleOrder SaleOrder { get; set; }
public int ProductCodeId { get; set; }
public ProductCode ProductCode { get; set; }
public int Quantity { get; set; }
}
public class ProductCode
{
public int ProductCodeId { get; set; }
public string Value { get; set; }
}
public class Carton
{
public int CartonId { get; set; }
public string BoxID { get; set; }
public int ProductCodeId { get; set; }
public ProductCode ProductCode { get; set; }
public int? SaleOrderId { get; set; }
public SaleOrder? SaleOrder { get; set; }
}
A Product Code and Quantity make up a rule, and a Sale Order can have many Rules and Cartons, Cartons can only be added to the Sales Order if the Product Code matches one of the rules, I am trying to query a breakdown of the data for a single Sale Order, including:
The SaleOrderRuleId
The Product Code
The Total Cartons scanned for this Rule
The Total Quantity required for this Rule And
A list of the Scanned Cartons for the rule (just the BoxID and CartonId)
I came up with the following query:
var saleOrderCartonCountBreakdown = await
(from c in _context.Cartons
where c.SaleOrderId == id
group c by new
{
c.ProductCodeId,
} into g
select new
{
ProductCodeId = g.Key.ProductCodeId,
CartonInfo = g.Select(x =>
new SaleOrderCartonBreakdownCarton {
CartonId = x.CartonId,
BoxID = x.BoxID
}).ToList(),
Count = g.Count()
} into gv
join pc in _context.ProductCodes on gv.ProductCodeId equals pc.ProductCodeId
join sor in _context.SaleOrderRules on gv.ProductCodeId equals sor.ProductCodeId
select new SaleOrderCartonBreakdownModel
{
SaleOrderRuleId = sor.SaleOrderRuleId,
ProductCode = pc.Value,
TotalScanned = gv.Count,
TotalRequired = sor.Quantity,
CartonList = gv.CartonInfo.ToList()
}).ToListAsync();
This works, but it only includes data if there is atleast one scanned carton for a product code, the intention is to also include the product codes for rules which do not have any cartons scanned in yet.
I'm fairly certain this is because I am starting on the Cartons table, however my attempts to rewrite the query to start on the SaleOrderRules and output the same result have been unsuccessful.
Any help is much appreciated :)

How to get specific columns with one to many relationship

I have 3 tables , one to many relationship.
I need to get only specific columns with SelectMany method.
I need to get only Categories.CategoryName and Comments.CommentDate of the selected News object.
Here is my code
News news = db.News.Include(w => w.Categories)
.Include(w => w.Comments).SingleOrDefault(n => n.NewsId == Id);
Here are my Entities:
News Entity:
public partial class News
{
public News()
{
this.Categories = new HashSet<Category>();
this.Comments = new HashSet<Comment>();
}
public int NewsId { get; set; }
public string NewsTitle { get; set; }
public string NewsBody { get; set; }
public System.DateTime NewsDate { get; set; }
public string NewsImagePath { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
Category Entity:
public partial class Category
{
public Category()
{
this.News = new HashSet<News>();
}
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<News> News { get; set; }
}
Comment Entity:
public partial class Comment
{
public Comment()
{
this.News = new HashSet<News>();
}
public int CommentId { get; set; }
public string CommentBody { get; set; }
public Nullable<System.DateTime> CommentDate { get; set; }
public virtual ICollection<News> News { get; set; }
}
This LINQ query should take care of it:
var query =
from news in db.News
where news.Id == Id
let categoryNames =
from category in news.Categories
select category.Name
let commentDates =
from comment in news.Comments
select comment.CommentDate
select new {
CategoryNames = categoryNames.ToList(),
CommentDates = commentDates.ToList()
};
That query is not using SelectMany, but that wouldn't help you, since then you wouldn't be able to group your categories and comments by news items. Since categories and comments are not directly connected, you'd need two SelectManys and then you'd need to cross join the results. That would obviously not be what you want.
Maybe try using the following?
var categoryNames = news.Categories.Select(c=>c.CategoryName);
var commentDates = news.Comments.Select(c=>c.CommentDate);
Note that SelectMany is used to flatten lists.For example, lets say you have collection of news matching certain search criteria, and then you use SelectMany to collect all the Categories/Comments of these news set, in a flat list.

How to join tables using LINQ to Entities query?

I have a simple db structure:
public class Person
{
[Key]
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Transport
{
[Key]
public int TransportID { get; set; }
public string Model { get; set; }
public string Brand { get; set; }
}
public class Accident
{
[Key]
public int AccsidentID { get; set; }
public DateTime AccidentDate { get; set; }
public int TransportID { get; set; }
[ForeignKey("TransportID")]
public virtual Transport Transport { get; set; }
public int PersonID { get; set; }
[ForeignKey("PersonID")]
public virtual Person Person { get; set; }
}
I need to create a list of accidents, wich I could pass to WPF form (using MVVM)
First I created new class witch I would like to see in my GridControl
public class AccsidentObject
{
[Key]
public int AccidentID { get; set; }
public DateTime AccidentDate { get; set; }
public int TransportID { get; set; }
public string Model { get; set; }
public string Brand { get; set; }
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Could you please give me examples:
if I want to get list of all values from Accident table including data from Transport and Person tables
if I want to get Accident list grouped by TransportID (also include data from Person and Transport tables)
I am getting data from Linq query:
var result = from ac in DBContext.Accidents select ac;
List<Accident> accidentList = result.toList();
But I need to add some fields to list from other tables, what would be a code?
What do I do wrong and could not construct a list of AccidentObject, maybe there are some mistake in my DBContext, lists o something... Could you please help me to understand List elements??
Considering to 2 part I wrote:
var result = from ac in DBContext.Accidents select ac;
result = result.GroupBy(g => g.TransportID).toList();
And now I need to add some Transport details and format AccsidentObject list ...
To get an entity (or collection of entities) with associations eagerly populated use the Include extension method, or include in a final projection into your type:
var res = await (from a in ctx.Accidents
select new AccsidentObject {
AccidentID = a.AccidentID,
TransportID = a.Transport.TransportID,
Model = a.Transport.Model,
// …
}).ToListAsync();
You can use groupby in a LINQ comprehension expression to group by something. In the result the Key property is the thing grouped by and each instance is a collection of all things grouped by.
var res = await (from a in ctx.Accidents
group by a.TransportID into g
select new {
TransportID = g.Key,
Accidents = g
}).ToListAsync();
In the resulting anonymous types the Accidents property with be a collection of Accident.
var accidents = DBContext.Accidents.Select( a => new AccidentObject
{
AccidentID = a.AccidentId,
AccidentDate
TransportID
Model
Brand = a.Transport.Brand,
PersonID = a.Person.PersonID,
FirstName
LastName
});
and fill in the blanks in much the same way.
here's a linq example without using lambda expressions, that includes a group by clause if you prefer it: Linq to sql select into a new class

How to create a list of objects based on a value that the object contains in a list of objects C#

I'm looking for a help.
I'm working an exercise based on MVC.
My model contains 2 classes. The DVD and the Category
public class DVD
{
public int ID
{ get; set; }
public string Title
{ get; set; }
public decimal Price
{ get; set; }
public int Quantity
{ get; set; }
public int Duration
{ get; set; }
public string Image
{ get; set; }
public virtual IList<Category> Categories_List
{ get; set; }}
Now the Category which is a method contains the following
public class Category
{
public int Id
{ get; set; }
public string Title
{ get; set; }
public virtual IList<DVD> DVDs
{ get; set; } }
Both DVD and Category are under the Model folder.
What I want to do is to create a list in my controller of the Category (inside the method of public ActionResult Details(int id = 0) )
to collect all the dvds which are in the category with the id 1 for example.
I found something simillar but I have problem when I have to check if the DVD's category id is the same with the one I'm looking for.
Search list of object based on another list of object c#
Can anyone help me to do it?
Thank you
Use LINQ Where. This will return call of the movies that match a particular category:
var moviesMatchingCategory = _masterMovieList.Where(ml => ml.Categories_List.Any(cl => cl.Id == categoryIdToCompare)).ToList();
If you can use linq this will help:
public IEnumerable<DVD> FindDvdByCategoryId(int categoryId, IEnumerable<DVD> dvdEnumerable)
{
return dvdEnumerable.Where(dvd => dvd.Categories_List.Any(c => c.Id == categoryId)).ToList();
}
List<DVD> list = dvds.Where(x=>x.Categories_List.Contains(y=>y.Id==Id)).ToList();
Try the above.

c#. EF entity sql. How to get entity with related objects?

I have made simple model for example.
public class Publisher
{
public int Id { get; set; }
public string Title { get; set; }
public Address Location { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
public class Address
{
public string Country { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string HouseNumber { get; set; }
}
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int LanguageId { get; set; }
public int? PublisherId { get; set; }
}
I need to get publishers with related books. I know how to do it using linq to entities. Is it possible to solve a problem using entity sql?
public class CatalogContext : DbContext {...}
public List<Publisher> GetByCity(string city)
{
var result = new List<Publisher>();
string queryString;
queryString = String.Format(#"SELECT VALUE row(a,b)
FROM CatalogContext.Publishers AS a
join CatalogContext.Books AS b on a.Id = b.PublisherId
WHERE a.Location.City = '{0}'", city);
var rows = ((IObjectContextAdapter)_context).ObjectContext.CreateQuery<DbDataRecord>(queryString).ToList();
return ???
}
Query returns required data but it's List<DbDataRecord> - list of pairs <publisher, book>. How to translate it to list of publishers with filled navigation property "Books"?
Is it possible to write query which directly returns List<Publisher>?
you can do the following:
var result = ObjectContext.Publishers.Include("Books").Include("Locations")
.Where(c => c.Location.City = "SOME_CITY").Select(c => c);
Include - basically joins the table.
Then you can drill down to books by doing the following:
var test = result[0].Books;
Why are you using direct sql command instead of Entity Framework code style?

Categories

Resources