Convert MS SQL to Entity Framework - sql

I trying to learn MVC, but while I try search customers purchased products I can't write with Entity Framework. I can search with MS SQL query, but I can't convert to Entity Framework.My codes;
Controller:
public ActionResult Orders()
{
Customer c = db.Customers.Find(Session["UserID"]);
List<Order> userorders= db.Orders.Where(x => x.CustomerID == c.ID).ToList();
List<OrderProduct> orderproducts = db.OrderProducts.Where(x => x.OrderID = userorders.ID); //This code not work
return View();
}
Database:
I try to convert this MS SQL code to Entity Framework;
"select ID from Products where ID IN (select ProductID from OrderProduct where OrderID IN (select ID from Orders where CustomerID = 1))"
If you can convert this MS SQL code to Entity Framework thats enough for me.
Thanks for anyone help and so sorry my bad English.

To retrieve all OrderProducts of the customer with ID 1, try this:
var orderProducts = db.OrderProduct
.Where(p => p.Orders.Any(o => o.Customers.Any(c => c.Id == 1)))
.ToList();
To retrieve the ID only, you can do it this way:
var productIds = db.OrderProduct
.Where(p => p.Orders.Any(o => o.Customers.Any(c => c.Id == 1)))
.Select(p => p.ProductId)
.ToList();

thanks for help but this is only orderproduct list. I need order list. I try this code (I edited JanneP's code. Thanks so much JanneP):
List<Product> products = (from co in db.Customers
join o in db.Orders on co.ID equals o.CustomerID
join op in db.OrderProducts on o.ID equals op.OrderID
join p in db.Products on op.ProductID equals p.ID
where co.ID == c.ID
select p).ToList();
This code find one customers ordered products. And it works.
Thanks everyone for help.

You could create a join condition. Also, where conditions need to be presented with two equal signs, not one. This should work:
List<OrderProduct> ürünler = (from c in db.Customers
join o in db.Orders on c.ID equals o.CustomerID
join op in db.OrderProducts on o.ID equals op.OrderID
where c.ID == 1
select op).ToList();

Since your database has been set up properly with Foreign Keys constraints, Entity Framework will be able to use 'navigation properties'. This allows you to write your query very easily as follows.
List<Product> products = db.Products.Where(e => e.OrderProduct.Orders.CustomerID == 1).ToList();
In your original SQL you only wanted the product IDs. Here's how you would do that.
List<int> productIds = db.Products.Where(e => e.OrderProduct.Orders.CustomerID == 1).Select(e => e.ID).ToList();
For people who have a sound grip on SQL but are new to Entity Framework and Linq, a useful search term is '101 LINQ samples'.

Just use the Include to retrieve the product with each order.
List<Order> userorders= db.Orders.Include(a=>a.Product).Where(x => x.CustomerID == c.ID).ToList();
This will retrieve the orders and with each order the product.
You can change the Include to add more navigation properties, I am assuming you have a Product property inside the Order class, you can change the name ift was wrong

Related

I need to get Subject name with total number of Book

I have a SQL Query which I want to convert in Linq or want to show data
as pictured here
Here is the query:
select sae_subcategorymaster.subject, count(sae_tblbookdetail.title)
from sae_tblbookdetail inner join sae_subcategorymaster
on sae_subcategorymaster.subject=sae_tblbookdetail.subject
group by sae_subcategorymaster.subject
What is a simple way to do this?
Grouping is supported in LinqEF. Provided you have your entities related. (Books have a reference to their subcategory.)
var totals = context.Books
.GroupBy(book => book.SubCategory.Subject)
.Select(group => new
{
Subject = group.Key,
BookCount = group.Count()
}).ToList();

Where could i find table details on sap business one forms?

I hope you could help me find where could i found the table name and location as it only shows as a form..
i hope you could help..
That field comes from table ITM1 and the field is named "Price".
You should consider pricelists per business partner in fetching this. Look at query below.
// Default price
listNum = _db.OCRDs.Where(x => x.CardCode == _cCode.ValueEx).Select(y => y.ListNum).FirstOrDefault();
if (listNum != null)
{
defaultPrice = (from oi in _db.OITMs
join it in _db.ITM1 on oi.ItemCode equals it.ItemCode
join op in _db.OPLNs on it.PriceList equals op.ListNum
where (oi.ItemCode == _itemNo.ValueEx
&& op.ListNum == listNum)
select it.Price).FirstOrDefault();
}

fetch required property using Criteria API?

I have customer and customerAddress class. CustomerAddress class have country n state object.When I load customer i want CustomerAddress also and in customerAddress i want to load only contryName and countryID other details must be null.
In short SQL Query which i want to genrate by Criteria APT is
SELECT Customer.Name, Country.CountryName,
Country.CountryID AS CountryID,
CustomerAddress.LocalAddressLine1
FROM Customer INNER JOIN CustomerAddress
ON Customer.CustomerID = CustomerAddress.CustomerID
INNER JOIN Country
ON CustomerAddress.CountryID = Country.CountryID
to achive this i did
ICriteria criteria = session.CreateCriteria(typeof(Customer), "Customer")
.CreateAlias("Customer.CustomerAddressList", "CustomerAddressList", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.CreateCriteria("CustomerAddressList.Country", "Country", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.SetProjection(Projections.ProjectionList().Add(Projections.Property("Country.CountryID"))
.Add(Projections.Property("Country.CountryName")))
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(Customer)))
.Add(Restrictions.Eq("Customer.EstablishmentId", CustomerId));
but this gives me Error. How can do this.
How to get specified columns using Criteria API.?
Edited As per guidence By #Firo
i moved .Add(Restrictions.Eq("Customer.EstablishmentId", CustomerId)) before SetProjection so my code is now
ICriteria criteria = session.CreateCriteria(typeof(Customer), "Customer")
.CreateAlias("Customer.CustomerAddressList", "CustomerAddressList", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.CreateCriteria("CustomerAddressList.Country", "Country", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.Add(Restrictions.Eq("Customer.EstablishmentId", CustomerId))
.SetProjection(Projections.ProjectionList().Add(Projections.Property("Country.CountryID"))
.Add(Projections.Property("Country.CountryName")))
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(Customer)));
customer = criteria.UniqueResult<Customer>();
This will execute successfully no error will occure but when i look for customer object all its property is null.
for AliasToBean to work correctly you need to explicitly specify the alias
.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("Country.CountryID"), "CountryID")
.Add(Projections.Property("Country.CountryName"), "CountryName"))
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(Country)));
Although you can supposedly do this using a Transformer, it may not be worth doing. For one thing it may be clearer to construct the instances yourself directly in the method. If you specify a ProjectionsList with multiple Projections on your Criteria instance then Hibernate will bring back a result list of Object[] So ...
List<Object[]> results = crit.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("Country.CountryID"), "CountryID")
.Add(Projections.Property("Country.CountryName"), "CountryName")).list();
List<Customer> customers = new ArrayList<Customer>();
for ( Object[] row: results ) {
Customer c = new Customer();
c.setCountryId((Long) row[0]);
// etc. for other properties
customers.add(c);
}
See also AliasToBeanResultTransformer(MyDTO.class) fails to instantiate MyDTO

Complex query, use :includes and :joins at the same time?

(Using Rails 3.1.3)
I have an app that manages products. I import the products from several resellers and they all name their categories different. Because of this I have resellercategories that are mapped to my own subcategories.
Categories
Subcategories (belongs_to Category)
Resellercategories (belongs_to Subcategory)
Products (belongs_to Resellercategory)
You can see the models and how the relations are defined here:
http://snipt.net/Linuus/category-and-subcategory?key=38ba590408ac4233927a06046eeca30d
On my site I want to display the categories and their subcategories, easy.
If a user filters the products for, say, only 'female' products I want to filter also the categories and subcategories so that only categories and subcategories that have 'female' products are displayed. The gender is stored in the products.
So, how can I do this?
I tried to create a query like this:
http://snipt.net/Linuus/categories-1/?key=2d5d54fd573f0afe60eaa3c47a23fd4d
which (I think) filters the correct Categories. However, when I do something like:
#menu_categories.each do |c|
c.subcategories.each do |sc|
# do something...
end
end
It still queries all the subcategories whether or not they have female products. So, I got a suggestion over at the Ruby on Rails Google Group to eagerly load the :subcategories using .includes(). So, something like this:
Category.includes(:subcategories)
.joins("INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id")
.joins("INNER JOIN products AS p ON r.id = p.resellercategory_id")
.group("categories.id")
.order("categories.name ASC")
.where("p.gender = 'unisex' OR p.gender = 'female'")
.where("subcategories.id > 0") # Dummy to trigger eager loading
However, when mixing .includes() and .joins() the includes seems to fail to eager load anything. Thus throwing the error below:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: subcategories.id:
SELECT "categories".* FROM "categories"
INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id
INNER JOIN products AS p ON r.id = p.resellercategory_id
WHERE (p.gender = 'unisex' OR p.gender = 'female')
GROUP BY categories.id
ORDER BY categories.name ASC
Is this behavior expected? Is it a bug?
Am I trying to do this the right way or is there a better way to do it?
Any help is very appreciated.
(The discussion on RoR Google Group: https://groups.google.com/forum/?pli=1#!topic/rubyonrails-talk/UkCF7jbehHk)
Solution:
Ok, so the solution is to use eager_load() instead of includes(). I also had to remove group()
This seems to work for me:
Category.eager_load(:subcategories)
.joins("INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id")
.joins("INNER JOIN products AS p ON r.id = p.resellercategory_id")
.order("categories.name ASC")
.where("p.gender = 'unisex' OR p.gender = 'female'")
Rails does not always use joins to realise an include. You can force it too by doing eager_load rather than includes.
This AR chain looks a lot cleaner.
Category.joins({:subcategories =>
{:resellercategories =>
:products}})
.includes(:subcategories)
.where('products.gender = unisex OR
products.gender = ?', gender)
BUT I don't think it will solve your original problem of getting all the subcategories. To solve that you'll actually have to query the association.
#menu_categories.each do |c|
c.subcategories.joins({:resellercategories =>
:products}})
.where('products.gender = unisex OR
products.gender = ?', gender)
.each do |sc|
# do something...
end
end

NHibernate: returning List<EntityType> not List<Object[]> when using grouping

when using Nhiberante Criteria API or HQL with grouping, query returns list of arrays of entity properties List<Object[]> at which grouping was made. If I need to return only certain property how can I do that? preferably with Nhiberane API if possible
Have you tried using the Transformers class?
See section 16.1.5
With HQL, you just SELECT the properties you want:
var query = Session.CreateQuery("select p.Id, p.Price from Products p where p.Status = 'A'")
.List().Cast<object[]>();
It's similar with NHibernate.Linq:
var query = from p in Session.Linq<Product>()
where p.Status == "A"
select new
{
p.Id, p.Price
};