Computing NonMapped members with in query in Entity Framework - c#

Suppose I have an entity:
public class Table {
[Key]
[Column]
public long TableId { get; set; }
[ForeignKey("TableId")]
[JsonIgnore]
[Association("Diners", "TableId", "TableId")]
public List<Diner> DinersAtTable { get; set; }
[NotMapped]
public int Total { get; set; }
}
public class Diner {
[Key]
[Column]
public long DinerId { get; set; }
public long TableId { get; set; }
}
public class Item {
[Key]
[Column]
public long ItemId { get; set; }
public long DinerId { get; set; }
public long Price { get; set; }
}
I want to fill Total with the sum of the Prices of all the Items ordered by the diners, but since I'm not really interested in the Items themselves, I would like to fill the Total in the query which gets me the Table entity.
So, I'd like something like:
var query = ctx.Tables.Include(t => t.DinersAtTable)
.Include(t = t.DinersAtTable.Select(d => d.Include(Items)))
.AssignToUnmapped(t => t.Total = t.Diners.Items.Sum()).Select(t => t.TableId, t.Total)
Obviously AssignToUnmapped and the final Select is what I'm not sure how to achieve. Any idea how I should do that?

Related

Ordering Items by List Item in EntityFramework

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))

How do I store a list of objects in field using Entity Framework 6

I am trying to code a payment process for an e-commerce solution and I want to gather all products in the shopping cart, but then inside a List<OrderProducts> and then store that list into an an object Order.
The POCO classes are below:
Order.cs
public class Order
{
public int Id { get; set; }
public double TotalAmount { get; set; }
public IdentityUser UserAccount { get; set; }
public virtual ICollection<OrderProduct> OrderProduct { get; set; }
public DateTime OrderDate { get; set; }
public bool IsComplete { get; set; }
}
OrderProduct.cs
public class OrderProduct
{
public int Id { get; set; }
public Order Order { get; set; }
public Product Product { get; set; }
public int Quantity { get; set; }
}
After running migrations and updating the database, it seems the OrderProduct column in the Order table does not even show in the database design.
Can someone please help or give a better solution based on the scenario above?
Change your OrderProduct class, then regenerate your migration:
public class OrderProduct
{
[Key]
public int Id { get; set; }
public int OrderId {get;set;}
[ForeignKey(nameof(OrderId))]
public virtual Order Order { get; set; }
public Product Product { get; set; }
public int Quantity { get; set; }
}

Entity Framework Code First creates classes from two tables and relationships one to many

I create an application and as an example for testing I take a table of orders. I have questions about class modeling.
I have 3 classes:
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
public class Part
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
class Order
{
public Order()
{
Cars = new List<Car>();
Parts = new List<Part>();
}
public int OrderId { get; set; }
public int CarId { get; set; }
public int PartId { get; set; }
public ICollection<Car> Cars { get; set; }
public ICollection<Part> Parts { get; set; }
}
I do not know if this model is ok. What do you think? Because something does not go here: / In the application:
I can not add cars or parts to the order that I do not have in the database.
In the table of orders I would like to see only the order Id, the value of the order, and the Id of the car and Id of the part that was bought.
 
I would like the Car and Part tables to have no data about orders. I would like to only add parts or cars in the application, later only be able to select from them in the order section.
Let's start with the physical tables you will need:
Part { Id, Name, Price }
Car { Id, Name, Price }
Order { Id }
OrderPart* { OrderId, PartId }
OrderCar* { OrderId, CarId }
The last two tables are called "join tables" because you need them to be able to store multiple parts and multiple cars on the same order, but are not really tables you think of as being part of your model.
Entity Framework will automatically make these join tables if you set up your classes as follows:
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Part
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
class Order
{
public Order()
{
Cars = new List<Car>();
Parts = new List<Part>();
}
public int OrderId { get; set; }
public virtual ICollection<Car> Cars { get; set; }
public virtual ICollection<Part> Parts { get; set; }
}
Note that the ICollection<> properties on the Car and Part table will be the clue to EF that it needs to make the join table. Also, remember that you need "virtual" on your navigation properties.
It is good model ?
One Pizza may have a few idgredience
One Pizza may have one sauce under the cheese
One Order may have a few idgredience and a few sauces.
It is my classes :
public class Suace
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Pizza
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public ICollection<Idgredient> Idgredients { get; set; }
public Sauce Sauce {get;set;}
public virtual ICollection<Order> Orders { get; set; }
}
class Order
{
public Order()
{
Cars = new List<Car>();
Parts = new List<Part>();
}
public int OrderId { get; set; }
public virtual ICollection<Car> Suace { get; set; }
public virtual ICollection<Part> Pizza { get; set; }
}
public class Idgredient
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Pizza> Pizzas { get; set; }
}

Sum Related Collection By Property in Entity Framework (Lazy Loaded)

I am in need of some assistance with an Entity Framework query. I have the following entities:
public class Invoice
{
public Guid Id { get; set; }
public DateTime CreateDate { get; set; }
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
public Guid CreatedById { get; set; }
public bool Approved { get; set; }
public virtual ICollection<InvoiceDetail> Details { get; set; }
}
public class InvoiceDetail
{
public Guid Id { get; set; }
[ForeignKey("InvoiceId")]
public virtual Invoice Invoice { get; set; }
public Guid InvoiceId { get; set; }
public string Item { get; set; }
public string Description { get; set; }
public decimal Quantity { get; set; }
public decimal UnitCost { get; set; }
public decimal Discount { get; set; }
}
I am trying to sum the total of all the items where an invoice is Approved. The problem I'm having is the syntax on getting to the InvoiceDetail level once I filter for the Approved = 1:
var myInvoices = context.Invoices.Where(i => i.CreatedById == userId).Include(i => i.CreatedBy).Include(i => i.Details);
var approvedTotal = myInvoices.Where(i => i.Approved == 1).Select([GET TO DETAILS???]);
// my goal is to get the following sum for each detail for all of the approved invoices:
// ((d.Quantity * d.UnitCost) - d.Discount)
Assuming that you wanted to get a sum total of all details after the given calculation had been performed you could do something like this:
var approvedTotal = invoices.Where(invoice => invoice.Approved)
.Select(invoice => invoice.Details.Sum(detail => ((detail.Quantity * detail.UnitCost) - detail.Discount)));
So this gives you one total per invoice.

Entity Framework AsNoTracking Not Working In GroupJoin

I have the following model
public class Rate
{
public Guid Id { get; set; } // PK
public int SpecialId { get; set; }
[Column(TypeName = "Money")]
public decimal Rental { get; set; }
public virtual Vehicle Vehicle { get; set; }
}
And the following...
public class Vehicle
{
public Guid Id { get; set; } // PK
public int SpecialId { get; set; }
public string Manufacturer { get; set; }
public string Model { get; set; }
}
I am joining the two on SpecialId using a GroupJoin using the following query.
var query = _context.Vehicle.AsNoTracking()
.GroupJoin(_context.Rate.AsNoTracking(),
vehicle => vehicle.SpecialId,
rate => rate.SpecialId,
(v, r) => new VehicleQuery
{
Rates = r,
Vehicle = v
}).AsNoTracking();
... and returning a VehicleQuery model (Show below)
public class VehicleQuery
{
public Vehicle Vehicle { get; set; }
public IEnumerable<Rate> Rates { get; set; }
}
However, even though I have AsNoTracking on the Rate table and the final query, when I look at the results in the debugger.
I can see that the Rates are still tracked (DynamicProxies). However the Vehicle is fine and showing as normal class and not a dynamic proxy/tracked.
I have even tried r.ToList() in the VehicleQuery but it's still showing as a DynamicProxie?
Any help appreciated.

Categories