Laravel Eloquent Query Builder (with JOIN) - eloquent

Tables
VENDOR
id name approved
PRODUCT
id name price instock fky_prod_vendor_id
Relationship
VENDOR(hasMany products()) <- (one-to-many) -> (hasOne vendor())PRODUCT
Query
How can I get all the products in-stock of a approved vendor using Eloquent given that the relationships are defined in Model?
My SQL is as following, but I need to use Eloquent relationship to achive the following.
select product.id
from product, vendor
where product.fky_prod_vendor_id = vendor.id
and vendor.approved = 'y'
and product.instock > 0
Thanks
K

As relationships are present, we can achieve this using Querying Relationship Existence method whereHas as rightly pointed out by #svrnm
PRODUCT::where('instock','>',0)
->whereHas('vendor', function ($query) { // Using Eloquent Query Existence, first parameter is name of relationship method, inside function is where clause on related model
$query->where('approved','y');
})->get();
That's magic of Laravel
Thanks
K

Related

How to use Entity Framework with a database without relationships defined

I am new to EF so please bear with me. I am using Entity Framework with an existing database in which the relationships are not defined.
Using EF, I am able to produce the model, but obviously the 'navigational properties' are not working. Is there a way I can specify the mapping between the entities?
For example, in my Product entity, I have a field CategoryID_fk (maps to Category entity). But since the relationships are not defined, I cannot load a Category while loading a Product entity.
Can someone guide me in this regard?
I do understand that it would be preferable to refactor our database but I am unable to do that now. Thanks in advance.
This link is very useful.http://www.entityframeworktutorial.net/
I think field names are not suitable conventions.Try to change field name as CategoryId or Category_CategoryId .I think it will work
Yes, you can do a group join. Basically you will retrieve Products and Category in separate queries and take an approach as indicated in this answer.
Something along these lines:
var productCategoryList = products.GroupJoin
(
categories,
p=> p.productId,
c=> c.CategoryId,
(p, c) => new ProductCategory
{
//Create your Product Category model here
}
).AsEnumerable();

EF LINQ to Entites query for a Many to Many relationship

trying to work out how to do LINQ to Entities query for a many to many relationship which has a junction with fields table.
Below are the Domains models (I am using View models, but keeping it simple for this example).
Student Domain model
StudentID (PK)
ICollection<StudentCourse> StudentCourses
StudentCourse Domain model
StudentCourseID (PK)
StudentID (FK)
CourseID (FK)
ForAdult
ForSeniour
Description
Course Domain model
CourseID (PK)
ICollection<StudentCourse> StudentCourses
Note:
Since the junction table (i.e. StudentCourse) contains fields other than the two foreign keys, EF will create an entity for this.
Lazy Loading
I've got this working for lazy loading. The Navigation properties have been declared with the 'virtual' keyword.
The Query way - works!
var student = (from s in context.Students
where s.StudentID == id
select s).SingleOrDefault<Student>()
The Method way - works!
Student student = context.Students.Find(id);
Projection
BUT, I would prefer to do this with projection, for performance reasons, i.e. less trips to the database.
I'm really stuck on how to write up the LINQ to Entities query to return 1 student with (1 or) many StudentCourses.
I don't understand thoroughly how the Entity should be shaped, if you know what I mean.
For example, I've tried:
var myvar = from s in context.Students
from sc in s.StudentCourses
where s.StudentID == id
select s
What I require is to return an entity of Student with a collection of StudentCourses which could then be assigned to a Student and passed to the View model, then to the View.
Really would appreciate any help, as I've spent alot of time trying to solve this.
Also as a side note, I'm using the SingleOrDefault() method to cast the results of the var (IQueryable I think) to type Student. Is this the preferred way to cast?
You can get EF to eagerly load the related entities by using the Include method.
So using your LINQ example:
var student = (from s in context.Students
where s.StudentID == id
select s).Include("StudentCourses").FirstOrDefault();
And using extension methods:
var student = context.Students.Include("StudentCourses").FirstOrDefault(id);
The Student instance that is returned will have the StudentCourses collection populated with related entities. This should invoke only one SQL query that joins the tables together.
To answer your aside question: I prefer to use FirstOrDefault most of the time as above. The difference is that SingleOrDefault will expect exactly one result and throws an exception otherwise, whereas FirstOrDefault will return null if a student is not found.
Also, as the cast to Student is implicit, you don't need the <Student> type parameter.

How to use entity framework function to find certain cell

I have a table named product having product id, product bill id and.. the bill id is passed to my controller as a parameter.
I can use the entities from framework and find all rows with product id using
db.tbl_product.Find(product id).
But now i need to find all transactions using bill id. How do I do that??
Assuming tbl_product is a DbSet<Product> or something similar, you should be able to use LINQ to query the DbSet. To find a single item with a specific BillId property value, you would do something like this:
var product = db.tbl_product.FirstOrDefault(p => p.BillId == billId);
If there were multiple products with the same BillId, you could do the following:
var products = db.tbl_product.Where(p => p.BillId == billId);
It largely depends on the schema of the table and how you're using Entity Framework. I would highly recommend reading a book or tutorial on Entity Framework. There are lots of them out there, for example: Entity Framework Tutorial.

Whats the best way to join two tables with no database relationship using EF?

Ok, lets say you have two tables: Order and OrderLine and for some reason they do not have a foreign key relationship in the database (it's an example, live with it). Now, you want to join these two tables using Entity Framework and you cook up something like this:
using (var model = new Model())
{
var orders = from order in model.Order
join orderline in model.OrderLine on order.Id equals orderline.OrderId into orderlines
from ol in orderlines.DefaultIfEmpty()
select new {order = order, orderlines = orderlines};
}
Now, the above will produce orders and orderlines, left-joined and all, but it has numerous issues:
It's plain ugly
It returns an anonymous type
It returns multiple instances of the same order and I you have to do Distinct() on the client side because orders.Distinct() fails.
What I am looking for is a solution which is:
Pretty
Returns a statically well-known type instead of the anonymous type (I tried to project the query result, but I got into problems with the OrderLines)
Runs Distinct on the server side
Anyone?
Even if the database tables do not have a foreign key relationship setup, you can configure Entity Framework as if they do.
Add an OrderDetails navigation property to your Order class and then just query Orders.

JQgrid / Entity Framework Issue with entities that have a relationship

I have an entity that has a relationship with another entity. I am able to search on columns that are in the main entity, and include columns from the relationship entity. But I need to be able to filter the list (search) on columns that are not in the relationship entity.
for example
the Invoice Entity contains a customerId property, and is related to the Customer Entity which contains the customerName property
I need to be able to search / filter the grid by customerName.
I am new to entity framework, please help.
thanks
Carl
Your relation is 1->1. In these cases I usually return a custom class to the grid that has all the columns I need, including joins with other tables.
So basically what you need is to create a custom linq query with your resultset.
The mais query should follow this example:
var q = from i in ctx.Invoices
join c in ctx.Customers on i.CustomerID equals c.CustomerID
select new{InvoiceID=i.InvoiceID, InvoiceDate=i.Date, CustomerName=c.Name};
Now, assuming we receive a CustomerName variable with the string to filter by c.Name we could do:
if(!string.IsNullOrEmpty(CustomerName))
{
q = q.where(c => c.Name.ToLower().Contains(CustomerName.ToLower()));
}
Notice that I'm performing a ToLower() operation and a Contains, this will beahave as a LIKE ingnoring case sensitivity and searching for the string anywhere in the Customer Name.
At the end you'll return the q.ToList() serialized for the jqGrid...