Hand made queries vs findDependentRowset - zend-framework

I have built a pretty big application with Zend and i was wondering which would be better, building query by hand (using the Zend object model)
$db->select()
->form('table')
->join('table2',
'table.id = table2.table_id')
or going with the findDependentRowset method (Zend doc for findDependentRowSet).
I was wondering since i did a test to fetch data over multiple tables and display all the informations from a table and the findDependentRowset seemed to run slower. I might be wrong but i guess it makes a new query every time findDependentRowset is called as in :
$table1 = new Model_Table1;
$rowset = $table1-fetchAll();
foreach($rowset as $row){
$table2data = $row->findDependentRowset('Model_Table2', 'Map');
echo $row['field'] . ' ' . $table2data['field'];
}
So, which one is better and is there a way using findDependentRowset to build complexes queries that could span over 5 tables which would run as fast as a hand made query?
Thanks

Generally, build your own query is the best way to go, because zend will create just one object (or set of objects) and do just one query.
If you use findDependentRowset Zend will perform another query and build another object (or set) with the result for each call.
You should use this only in very specific cases.
See this question: PHP - Query single value per iteration or fetch all at start and retrieve from array?

Related

Is it possible to run a SQL query with EntityFramework that joins three tables between two databases?

So I've got a SQL query that is called from an API that I'm trying to write an integration test for. I have the method that prepares the data totally working, but I realized that I don't know how to actually execute the query to check that data (and run the test). Here is what the query looks like (slightly redacted to protect confidental data):
SELECT HeaderQuery.[headerid],
kaq.[applicationname],
HeaderQuery.[usersession],
HeaderQuery.[username],
HeaderQuery.[referringurl],
HeaderQuery.[route],
HeaderQuery.[method],
HeaderQuery.[logdate],
HeaderQuery.[logtype],
HeaderQuery.[statuscode],
HeaderQuery.[statusdescription],
DetailQuery.[detailid],
DetailQuery.[name],
DetailQuery.[value]
FROM [DATABASE1].[dbo].[apilogheader] HeaderQuery
LEFT JOIN [DATABASE1].[dbo].[apilogdetails] DetailQuery
ON HeaderQuery.[headerid] = DetailQuery.[headerid]
INNER JOIN [DATABASE2].[dbo].[apps] kaq
ON HeaderQuery.[applicationid] = kaq.[applicationid]
WHERE HeaderQuery.[applicationid] = #applicationid1
AND HeaderQuery.[logdate] >= #logdate2
AND HeaderQuery.[logdate] <= #logdate3
For the sake of the test, and considering I already have the SQL script, I was hoping to be able to just execute that script above (providing the where clause programmatically) using context.Database.SqlQuery<string>(QUERY) but since I have two different contexts, I'm not sure how to do that.
The short answer is no, EF doesn’t support cross database queries. However there are a few things you can try.
You can use two different database contexts (one for each database).
Run your respective queries and then merge / massage the data after
the query returns.
Create a database view and query the view through EF.
Using a SYNONYM
https://rachel53461.wordpress.com/2011/05/22/tricking-ef-to-span-multiple-databases/
If the databases are on the same server, you can try using a
DbCommandInterceptor
I’ve had this requirement before and personally like the view option.

Handling multiple tables using List<> in MVC

Here is my prob, am new to mvc,
I have used a List<> to get Data from Store Procedure as below,
List<Sp_MM_GetDetails_Result> lDetails = objDB.Sp_MM_GetDetails(ArticleURL).ToList();
Its working fine for me, but my SP returning 2 table of data. However my List<> taking only first table's data.
what should do if I wanted to get data from second table?
In C#, we can done this by using
DataSet.Table[1]
You need to execute the raw SqlCommand and execute Translate to map to the matching types.
Check this sample
https://msdn.microsoft.com/de-de/data/jj691402

How to pass a function (or expression) into the where clause of an Entity Framework Query

I'm getting errors when I try and do something like this:
from s in db.SomeDbSet where IsValid(s) select s
It errors telling me that it can't process IsValid.
Basically what I'm trying to do is filter based on another dbSet inside the Where that is linked and does an any, but it won't let me.
I've tried a million different ways of doing a Expression but I can't find the right way and building my own Extension method like Where doesn't seem to work either.
Thanks!
Can you paste your IsValid function?
In this case it's EF job to take LINQ syntax and turn it into SQL syntax.
EF can't turn your function into SQL. it only supports a set number of functions that have a clear SQL equivalent commend.
you have two options:
1) Rewrite the function as a series of supported commends. This will be turned into a SQL sub-query, Meaning a single trip to the database, For example:
// will only return records that have at least one related entity marked as full.
query.Where(m => m.ReletedEntities.Any(re => re.IsFull == true));
2) Get all the data from the database and then using Linq and your function work with the data. this will be done in memory using your actual function that will be called once for every item in the collection. You will also have to load the related entity collection. or it will still be an "entity framework translated to SQL query", And will fail if you use your function.

Fetch object by plain SQL query with SORM

Is it possible to fetch items by plain SQL query instead of building query by DSL using SORM?
For example is there an API for making something like
val metallica = Db.query[Artist].fromString("SELECT * FROM artist WHERE name = ?", "Metallica").fetchOne() // Option[Artist]
instead of
val metallica = Db.query[Artist].whereEqual("name", "Metallica").fetchOne() // Option[Artist]
Since populating an entity with collections and other structured values involves fetching data from multiple tables in an unjoinable way, the API for fetching it directly will most probably never get exposed. However another approach to this problem is currently being considered.
Here's how it could be implemented:
val artists : Seq[Artist]
= Db.fetchWithSql[Artist]("SELECT id FROM artist WHERE name = ?", "Metallica")
If this issue gets a notable support either here or, even better, here, it will probably get implemented in the next minor release.
Update
implemented in 0.3.1
If you want to fetch only one object (by 2 and more arguments) you can
also do the following:
by using Sorm Querier
Db.query[Artist].where(Querier.And(Querier.Equal("name", "Name"), Querier.Equal("surname", "surname"))).fetchOne()
or just
Db.query[Artist].whereEqual("name", "Name").whereEqual( "surname","surname").fetchOne()

Difference between LINQ to Entities with and without ObjectResult

I have the following LINQ to Entities query...
var results = from c in context.Contacts
select c;
which works fine in returning a collection of contacts. But I have seen sample code that does this instead...
ObjectResult<Contact> results = (from c in context.Contacts
select c).Execute();
What is the difference? The ObjectResult also has a collection of returned contacts. Is it just syntactic or is there a real fundamental difference?
ObjectResult<> is simply the type returned by EF when you start enumerating the IQueryable<> (i.e. context.Contacts).
So if you immediately enumerate either of your two queries, semantically it is the same.
The only difference is that in the first example if compose more query operations they will get appended to the query sent to the database when you enumerate, whereas in the second example they will get applied in memory by LINQ to Objects.
Also Execute(..) provides somewhat easier access to MergeOptions (like, should the database copy overwrite copies already in memory or visa versa). You can do this using the MergeOptions property on the ObjectQuery<> too, but that is a little more cumbersome.
Hope this helps
Alex