I have three objects:
Event (relationships: has many EventProducts)
Product (relationships: has many EventProducts)
EventProduct (relationships: with many Events, with many Products, has properties like quantity_sold, quantity_allocated, etc which should be stored per product and per event)
In my application, when someone clicks an Event, a new window initializes with a list of all products. From there they can modify cells I need to populate a datagrid in WPF such that when someone clicks an event. So in the context of this code, the Event is known and constant.
The issue I'm having is with creating default types of EventProduct.
What I need is to have a query where if there is no EventProduct in the DB, it will instantiate an EventProduct with EventProduct.Event = currentEvent
(currentEvent will be constant for all EventProducts created with this query) and EventProduct.Product = product
(product will change for each row)
This code works well when there is an associated EventProduct in the database. But if there isn't, my selection returns my Product just fine but the entire EventProduct is null.
var query2 = from product in dbContext.Products
join eventProduct in dbContext.EventProducts
on new { pIndex = product.index, eIndex = currentEvent.index }
equals new { pIndex = eventProduct.Product.index, eIndex = eventProduct.Event.index } into temp
from eventProduct in temp.DefaultIfEmpty() // this is my problem line
select new {
Product = product,
EventProduct = eventProduct
};
I have tried creating a constructor for EventProduct(Event e, Product p)
and passing in the values to the constructor in my DefaultIfEmpty()
method but I get errors that my constructor has to have 0 arguments to be used in that way. I can't do that because there is no way to tell my EventProduct() object which Event and Product it should be associated with if I do that.
I have also tried no constructor, just creating a new EventProduct and setting its properties but I get the error "The entity or complex type ...EventProduct cannot be constructed in a LINQ to Entites query".
At the end result, I want to select my Product
and EventProduct
. If there is no EventProduct
associated with both that Product
and Event
, then my EventProduct selection should be set to a default which has the currentEvent, the current row's Product, and all properties set to a default value (all are decimals and should be 0 in this case).
EDIT: I've just tried this query and it also gives me an Unsupported error:
var query2 = from product in dbContext.Products
join eventProduct in dbContext.EventProducts
on new { pIndex = product.index, eIndex = currentEvent.index }
equals new { pIndex = eventProduct.Product.index, eIndex = eventProduct.Event.index } into temp
from eventProduct in temp.DefaultIfEmpty()
select new {
Product = product,
EventProduct = eventProduct != null ?
eventProduct : new EventProduct
{
Product = product,
Event = currentEvent,
quantity_allocated = 0,
quantity_sold = 0,
quantity_sampled = 0
}
};
EDIT: Resolved with this technique:
1) Create an object because anonymous objects are read-only:
class Associations
{
public class ProductEventProduct
{
public Product Product { get; set; }
public EventProduct EventProduct { get; set; }
}
}
2) Foreach null object in the dataset, replace with a default object
var query = from product in dbContext.Products
join eventProduct in dbContext.EventProducts
on new { pIndex = product.index, eIndex = currentEvent.index }
equals new { pIndex = eventProduct.Product.index, eIndex = eventProduct.Event.index } into temp
from eventProduct in temp.DefaultIfEmpty()
select new Associations.ProductEventProduct {
Product = product,
EventProduct = eventProduct
};
var dataSource = query.ToList();
foreach (Associations.ProductEventProduct entry in dataSource)
{
if (entry.EventProduct == null)
{
entry.EventProduct = new EventProduct
{
Product = entry.Product,
Event = currentEvent,
quantity_allocated = 0,
quantity_sold = 0,
quantity_sampled = 0
};
}
}