I wanto to sipmly iaterate the result in view. Problem is that it do not accually work. What is missing? I read the documentatnion but they do not give a full ansver how to retrieve data by cusotm query. For me as a beinnger is hard to understend what do next ? I mean about this query I know how to pass it to view by viewmodel et. Please Help.
$config = $this->getServiceLocator()->get('config');
$adapter = new \Zend\Db\Adapter\Adapter($config[db]);
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('brokerzy');
$select->where(array('broker_status' => 'publish'));
$stm = $sql->prepareStatementForSqlObject($select);
$results = $stm->execute();
First, you probably shouldn't be doing queries in your controller, that's bad practice. These queries should be moved behind a service interface.
However, to answer your question (if I understand it), to pass the results of your query to a view, you should use a view model. It would look something like this.
//Your Code
$results = $stm->execute();
$viewModel = new \Zend\View\Model\ViewModel();
$viewModel->results = $results;
return $viewModel;
Related
I'm trying to get similar Document of another one . I'm using the Lucene.Net MoreLikeThis-Class to achieve this. For this i seperate my Documents in multiple Fields - Title and Content. Now creating the actual query results in an empty query without interesting Terms.
My could looks like this:
var queries = new List<Query>();
foreach(var docField in docFields)
var similarSearch = new MoreLikeThis(indexReader);
similarSearch.SetFieldNames(docField.fieldName);
similarSearch.Analyzer = new GermanAnalyzer(Version.LUCENE_30, new HashSet<string>(StopWords));
similarSearch.MinDocFreq = 1;
similarSearch.MinTermFreq = 1;
similarSearch.MinWordLen = 1;
similarSearch.Boost = true;
similarSearch.BoostFactor = boostFactor;
using(var reader = new StringReader(docField.Content)){
var searchQuery = similarSearch.Like(reader);
// debugging purpose
var queryString = searchQuery.ToString(); // empty
var terms = similarSearch.RetrieveInterestingTerms(reader); // also empty
queries.Add(searchQuery);
}
var booleanQuery = new BooleanQuery();
foreach(var moreLikeThisQuery in queries)
{
booleanQuery.Add(moreLikeThisQuery, Occur.SHOULD);
}
var topDocs = indexSearcher.Search(booleanQuery, maxNumberOfResults); // and of course no results obtained
So the question is:
Why there are no Terms / why there is no query generated?
I hope important thing's be seen, if not please help me to make my first question better :)
I got it to work.
The problem was, that i worked on the false directory.
I have different Solutions for creating the index and creating the queries and had a missmatch with the index-location.
So the generall solution would be:
Is your Querygenerating-Class fully initialized? (MinDocFreq, MinTermFreq, MinWordLen, has a Analyzer, set the fieldNames)
Is your used IndexReader correctly initialized?
I have a doctrine query which e.g. look like this:
$object = $this->createQueryBuilder('object')
->leftJoin('object.element', 'element')->addSelect('element')
->leftJoin('object.element2', 'element2')->addSelect('element2')
->leftJoin('object.many', 'many')->addSelect('many')
->leftJoin('many.element3', 'element3')->addSelect('element3')
->leftJoin('many.element4', 'element4')->addSelect('element4')
->where('object.id = 1')
->getQuery()
->getSingleResult();
The real query have more joins and need a lot of memory and the db performance is not good. In native SQL I would split it and load it correctly. What I want todo is load with the first query the object and some basic joined data. This would look like this:
$object = $this->createQueryBuilder('object')
->leftJoin('object.element', 'element')->addSelect('element')
->leftJoin('object.element2', 'element2')->addSelect('element2')
->where('object.id = 1')
->getQuery()
->getSingleResult();
Now I also want to load the many, many.element3 and many.element4. In seperate query. When I just use doctrine lazy loading feature it will create a SQL query foreach but I only want this as 1 query.
I know it would be possible to set EAGER on that relation but I only want to EAGER temporarily for this query not always when somebody join the object and access it.
Did solve my problem the following way:
In my object I did add a new set function for the collection.
/**
* Set manies.
*/
public function setManies($manies)
{
// this clear and foreach is needed to keep it as ArrayCollection so doctrine dont need for the unitofwork request the db again
$this->manies->clear();
foreach ($manies as $many) {
$this->manies->add($many);
}
return $this;
}
In the repository my code look like this:
$object = $this->createQueryBuilder('object')
->leftJoin('object.element', 'element')->addSelect('element')
->leftJoin('object.element2', 'element2')->addSelect('element2')
->where('object.id = 1')
->getQuery()
->getSingleResult();
$object->setManies($this->getEntityManager()->getRepository(Many::class)->loadByObjectId(
$object->getId()
));
return $object;
here the function in the many repository
// loadByObjectId in the many repository
$manies = $this->createQueryBuilder('many')
->leftJoin('many.element3', 'element3')->addSelect('element3')
->leftJoin('many.element4', 'element4')->addSelect('element4')
->where('many.object = 1')
->getQuery()
->getResult();
With this the SQL is successfully splitted in multiple request. In my case instead of 60000 rows in 1 request, I only had 40 rows affected in 4 request which make the hydration of the object a lot faster.
Hi I have a working public function that joins 3 tables to get values for 2 arrays. Now the process only has one table (table2) which contains all the colvalues required for the arrays.
I have tried everything I know to customise this so only table2 is used to get the arrays, but I just get blank results.
Can anyone point to me an example of something similar which takes values from a single table to get 2 separate arrays. I inherited this so I do not know what the thinking behind it was.
thank you in advance.
public function get2ColArray($condition)
{
$sql =new Sql($this->adapter);
$select = $sql->select();
$select->from('table1');
$select->columns(array('colval1'));
$select->join('table2', "table1.colval2 = table2.colval3", array('colval4'), 'inner');
$select->join('table3', "tabl1.colval1= table3.colval1", array('colval5'), 'left');
if(!empty($condition['in']))
foreach ($condition['in'] as $key=>$val) {
$select->where->in($key,$val);
}
if(!empty($condition['where']))
$select->where($condition['where']);
$select->order(array('table2.colval4'=>'ASC'));
$statement = $sql->prepareStatementForSqlObject($select);
$sql_result = $statement->execute();
if ($sql_result->count() > 0) {
$results = new ResultSet();
$data = $results->initialize($sql_result);
}
return $data;
}
Got it, its abit blunt but works, thanks ...
$select->from('table2');
$select->columns(array('colval1','colval_whateveryouwantaslongasitsintable2',));
I use RedBeanPHP 3.5.1 for ORM in my MVP project (powered by Nette FW).
I need to get ID of the last inserted element, that is owned by element from another table. Below you can find method representing functionality which I just described:
public function createSite($userId, $siteName, $feedUrl, $reloadTime, $reloadRate){
$site = R::dispense('site');
$site->user_id = $userId;
$site->name = $siteName;
$site->feed = $feedUrl;
$site->reload_time = $reloadTime;
$site->reload_rate = $reloadRate;
$user = R::load('user', $userId);
$user->ownSite[] = $site;
$id = R::store($user);
return $id;
}
Now I would assume that line
$id = R::store($user);
would store site ID into $id variable since it is owned by already existing user. Instead of that it fills variable with user ID that I have no further use for.
So my question is: How do I get last inserted ID of owned bean that was just created by calling R::store() method on parent (just loaded) bean? Is there an implementation on this in RedBean or do I have to do this manually?
I browsed every corner of RedBeanPHP project web but so far no luck.
Thanks for possible suggestions, guys.
Using common sense I finally figured out how to solve this elegantly and since no one answered my question so far let my just do that myself.
Since R::store($user) is capable of storing both $user and $site, there is misleadingly no need to store $site object manually.
But if you need to get last inserted id of owned bean, there is really no harm in doing so. By storing $site object framework will do the exact same thing and on top of that it returns resired id.
So the correct method implementation looks like this:
public function createSite($userId, $siteName, $feedUrl, $reloadTime, $reloadRate){
$site = R::dispense('site');
$site->user_id = $userId;
$site->name = $siteName;
$site->feed = $feedUrl;
$site->reload_time = $reloadTime;
$site->reload_rate = $reloadRate;
$user = R::load('user', $userId);
$user->ownSite[] = $site;
$id = R::store($site);
R::store($user);
return $id;
}
So in conclusion, hats off to RedBeanPHP ORM FW and I sincerely hope this helps people with similar problem in the future.
There is a function called R::findLast('...')
$last_record = R::findLast('...');
Not sure if this would have been a correct answer 7 years ago but at least now there is no need to do any kind of extra work:
$shop = R::dispense( 'shop' );
$shop->name = 'Antiques';
$vase = R::dispense( 'product' );
$vase->price = 25;
$shop->ownProductList[] = $vase
R::store( $shop );
echo $vase->$id; // <-- yes, id which was created by database is present here
Am developing a ViewModel/PresentationModel which is getting complex.
I want the Linq query to return an IQueryable<UserPresentationModel>
Using EntityFramework against MSSQL
Is it possible to do any sort of iteration over the set before returning it to the presentation layer ie
List<UserPresentationModel> list = new List<UserPresentationModel>();
foreach (var person in listOfPeople)
{
UserPresentationModel u = new UserPresentationModel();
int userUIStatus = GetColourStateOfPerson(person);
u.FirstName = person.FirstName;
u.UserUIStatus = userUIStatus;
list.Add(u);
}
return list
This feels like it would always be N+1, and I'd never get the advantages of deferred execution, composing of queries..
Or (and I think am answering my own question) do I need to think in a SQL set based manner.
First, we can convert your code to LINQ.
IEnumerable<UserPresentationModel> models =
from person in listOfPeople
select new UserPresentationModel
{
FirstName = person.FirstName,
UserUIStatus = GetColourStateOfPerson(person)
}
return models.ToList();
Now, if GetColourStateOfPerson is making a DB round-trip, you definitely want to pull that out.
IDictionary<int, int> colourStatesByPersonId = GetColourStatesOfPeople(listOfPeople);
IEnumerable<UserPresentationModel> models =
from person in listOfPeople
select new UserPresentationModel
{
FirstName = person.FirstName,
UserUIStatus = colourStatesByPersonId[person.PersonId]
}
return models.ToList();
You could probably manage to create a single LINQ query that grabs just the first names and colour states of the people you want in a single query, but you haven't provided enough information about your data context for me to help you with that.
I would personally avoid passing around an IQueryable, which could continue making database trips any time somebody touches it. Let your data layer get out all the data you're likely to need, compose it into a list, and return that.
use IEnumerable<T>.Aggregate() instead of looping.
return listOfPeople.Aggregate(new List<UserPresentationModel>(), person => {
return new UserPresentationModel {
FirstName = person.FirstName,
UserUIStatus = GetColourStateOfPerson(person)
};
}).AsQueryable();
return listOfPeople.AsEnumerable().Select(p =>
new UserPresentationModel
{
FirstName = p.FirstName,
UserUIStatus = GetColourStateOfPerson(p)
}).AsQueryable();
I'm assuming that listOfPeople is an IQueryable that will eventually execute against your database. If that is the case then AsEnumerable() is important because SQL Server won't know what to do with GetColourStateOfPerson(). AsEnumerable() will force the IQueryable's expression tree to execute, pull the resulting rows out of your database and then apply Select() transformation in code as oppose to in SQL Server.
If you can implement GetColourStateOfPerson() as a stored proc or database function then you can omit AsEnumerable() and AsQueryable() and allow execution to delay even longer.