Querying many to many relationship - vb.net

Every article I need to solve my problem seems to be in C# and I need a solution in VB.NET.
I'm using EF 6.0 with Database First model. Let me use the classic Customer product scenario to demonstrate my situation. In my database I have three tables Customer, Product and CustomerProduct. See this example in this link as mine is exactly the same.
After I generate my model from the database, my entity model diagram shows that the CustomerProduct has disappeared as expected and the the model shows a many to many relationship between Customer and Product also as expected with navigational properties of Products in Customer and Customers in Product.
All I want to do is find the product related to a customer pull out some data from both tables namely CustName and ProductName.
The SQL I would use is:
SELECT c.CustName, p.ProductName FROM Customer c
INNER JOIN CustomerProduct cp on c.CustomerId = cp.CustomerId
INNER JOIN Product p on cp.ProductId = p.ProductId
WHERE c.CustomerId=101
I don't know how to use the Addresses navigational property to access the Address data in one query.

You include them and then access them via the property in the Entity class.
Dim query = model.User.Include("Address").Include("UserAddressLink").Where(Function(o) o.UserId = 101).FirstOrDefault
If Not query Is Nothing Then
Dim houseNumber = query.Address.HouseNo 'uses the navigation property
End If

Thanks to InteXX I managed to work it out. This is my whole solution
Using db as new CustProdEntities
Dim query = db.Customers.Include(Function(U) U.Products).ToList
txtCustomer.Text = query.First.CustName
txtProduct.Text query.First.Products.First.ProdName
End Using
The bit I was stuck on was having to filter twice to the Product data. I'm not sure if there's an easier way to do this but it works for now.

Related

Populating data in GridView in a peculiar manner [Special Case]

http://imageshack.us/photo/my-images/837/6uvs.jpg/
I have the following tables and relationships.
When loading the NEW_CHALLAN form, I am trying to fill a Grid View with Product Details - Product Name, Stage, Pro, Katta, Packing, Rate, Quantity.
I am facing a problem (getting 0 records as result set) when using JOIN for this operation as there are no matching records(ChallanId, ProductId, OrderId) in the ChallanProductDetails table yet (when loading the form)
Any suggestions on how to solve this problem ?
If you are trying to load product details even tough there are no order/challan details then you can try something like below,
select a.productname,a.productprice,c.stage,c.pro...etc from product a
left outer join challanproductdetails b
on a.productid= b.productid
brother I am not sure what exactly your asking for is it to retrieve data from a view or two tables if you are retrieving only then why don't you create a view of two tables and just call it straight to the grid that will be easy.
Please correct me if I am wrong.

NHibernate entity mapping: Customer with latest order

I am developing a MVC3 application in c# and I am using NHibernate for the ORM part. I need to generate a list of all registered customers and their latest order. On the application side, this would require to go through all customers and retrieve all their orders to extract the latest one.
Unneeded overhead, isn't it?
On the database, I could create a view and model the entity accordingly, but then I cannot create new customers due to the fact that populating a view is not possible. So, any ideas or best practices how you solved such issues? Here's a sql query that would serve the needed information:
SELECT c.id, c.name, c.description, m.ordernumber AS latest_order, m.unixtime, m.id AS latest_order_id
FROM dbo.customer c
LEFT JOIN dbo.mailorder m ON c.id = m.customer_id
WHERE m.unixtime = (SELECT MAX(unixtime) FROM dbo.mailorder)
Any help is very much appreciated!
Best regards,
Martin
You can use formula to get last order for customer, something like this:
<property name="LatestOrder" formula="(SELECT MAX(dbo.mailorder.unixtime) FROM dbo.mailorder where dbo.mailorder.customer_id = ID)" />

MVC creating SQL views vs. putting calculations in the controller

I applied for a job, they required me to create a small MVC app before interview which I did. They rejected it saying that I had used bad practices. Please help me figure out what I did wrong!
The task involved a simple database with a Product and a load of Sales (a one to many).
I had to:
display a list of products with total sales
display and allow edition and deletion of the sales
My solution:
create a left joined SQL view which used a group and join to itself to get the sale totals. This table had one row per product
Create an inner joined SQL view with all of the product and sales data. This had one row per sale.
For #1, I just rendered out the view
For #2, I had to render out product details and sales details (a one to many on a single page) so I did the following in the controller:
public ActionResult Details(int id)
{
// get details for the selected product
var product = db.ProductsWithTotals.Where(q => q.ProductId == id).Single();
ViewData["CatalogueNumber"] = product.CatalogueNumber;
ViewData["Title"] = product.Title;
ViewData["Artist"] = product.Artist;
ViewData["TotalSold"] = product.TotalSold;
ViewData["ProductId"] = product.ProductId;
// then pass its sales lines to the view
var salesLines = db.SalesLineDetails.Where(q => q.ProductId == id);
return View(salesLines);
}
If anyone could explain how I could have done this more gracefully, it'd be greatly appreciated.
The only thing I personally would have done differently is:
Use EF (but yeah, L2S is fine for a quickie like this)
Create a ViewModel class for the details View. I use ViewData as sparingly as possible.
But yeah, nothing bad here and I agree that it was probably not a good place to work at. People also tend to make up vague reasons if they didn't want to say they didn't like your face.
/shrug

NHibernate Using SetProjection To Retrieve Individual Collection Items

I am trying to use Projections to Create a DTO from a Lead class. My DTO has, for example, a Home phone number, a mobile number and an email address, but the Lead Class has a collection of contact details. So I'm trying to find a way to retrieve each contact detail so that I can set the properties on the dto. I have tried using sub queries and projections but to no avail.
The SQL I'm trying to generate is something like this:
SELECT
A.LeadId,
B.ContactId,
B.Value,
C.ContactId,
C.Value,
D.ContactId
FROM Lead A
LEFT JOIN ContactDetail B ON A.LeadId=B.LeadId AND B.ContactType='Home Number'
LEFT JOIN ContactDetail C ON A.LeadId=C.LeadId AND C.ContactType='Mobile Number'
LEFT JOIN ContactDetail D ON A.LeadId=D.LeadId AND D.ContactType='Email Address'
So in short I'm trying to join to the same table 3 times based on different criteria, and I know that in NHibernate I can't use CreateAlias to join to the same table more than once and I'm anxious to know if this is possible using either the Criteria API or NHIbernate Linq. Thanks in advance for any help.
I would load the "regular" lead instance from nHibernate with its contact detail collection. Then I would use AutoMapper, to map it to the DTO class.
In my opinion, this is a much cleaner approach since you do not create special data access methods just for "simple" DTO mappings. And it's easier for refactoring since everything is expressed via "c sharp code".
Link to AutoMapper

Nhibernate: left outer join on subquery

Update take 2
here is the two queries i'm working with (paging is omitted in both queries)
i'd like to get the following query
SELECT *
FROM product
LEFT OUTER JOIN
(
SELECT *
FROM Cart
LEFT OUTER JOIN
cartproducts
ON Cart.Id = cartproducts.Cart_id
WHERE Cart.username = 'user'
)
AS CartFiltered
ON product.Id = CartFiltered.product_id
but i always seem to get
SELECT *
FROM product
LEFT OUTER JOIN
cartproducts
ON product.Id = cartproducts.Product_id
LEFT OUTER JOIN
Cart
ON
cartproducts.cart_id = cart.id
WHERE Cart.username = 'user'
How can i manage to create the first type of query?
I hope my question is clearer :) lack of clarity is sometimes a great enemy of mine :p
Update:
FWIW, i still haven't found the answer, and am currently loading the paged product data and the whole cart to display the correct object.
Crude solution but it works and it beats the combinatorials i've been through trying to make the Criteria API recognize me as its master. I would be very interested if somebody could happen to point me in the right direction though ;)
Hello,
i'm having a hard time writing the following query in the Criteria API, and i don't really see how to do it: i hope some people can help.
On the database, i have products. Theses products can be in many carts (one cart per user), and each cart can contain many products, so we have a manytomany relationship.
I would like to display a list of every product, along with a small icon next to it to inform the user that this particular product is already in the cart. What i did is i asked NHibernate for my products, and to do a left outer join on carts filtered by the cart's owner.
Dim critPage As ICriteria = Session.CreateCriteria(GetType(Product)) _
.SetFirstResult(pageNumber * itemsPerPage).SetMaxResults(itemsPerPage) _
.CreateCriteria("Carts", "c", SqlCommand.JoinType.LeftOuterJoin) _
.SetProjection(plist) _
.SetResultTransformer(New TypedResultTransformer(Of ProductWithCartInfo)) _
.Add(Expression.Eq("c.User", username))
the projection list is here to reduce the number of columns to what's interesting for the ProductWithCartInfo class. It contains only property projections.
The problem is that with this query, the cart filtering is applied to the whole result set and i don't see every product with its presence in the user's cart, but rather every product in the user's cart.
Is it possible to do a left outer join on a subquery with the Criteria API in Nhibernate? For information, i would like to keep it in the Criteria API if possible.
Thanks
I'm not sure I entirly follow your issue but it sounds very similar to an issue I had. I seems that when you have the nested (sub) criteira with NHibernate you loose some of the control. I was able to get around my issue but aliasing my tables instead of using the nested criteira.
Possibly try...
criteria.CreateAlias("Cart", "Cart", JoinType.LeftOuterJoin);
and then your filter on the cart will have to be an OR condition
ICriterion cartCriterion = Restrictions.Eq("Cart.User", username);
customerCriterion = Restrictions.Or(customerCriterion, Restrictions.IsNull("Cart.User"));
criteria.Add(customerCriterion);
Let me know if that helps you out... if not... maybe post the SQL that your criteria above is generating and where it needs to change.
Good Luck