1

さて、私はこれを機能させる方法を研究し、研究したという質問があります、そして私の人生のために私はできません!...おそらく私はこれを間違ってやっていて、最小限の情報が見つかりました..

timeclock setupという名前のテーブルがあります。このテーブルには、レコードが属するユーザーのIDであるnoteBy_idというフィールドがあります。

私が今やらなければならないのは、システム内の管理側です。このタイムレコーダーシステムを使用している会社は複数あると予想されるため、会社IDに基づいて結果をフィルタリングする必要があります。ユーザーテーブル、という名前のフィールドがありますparentcompany_id

だから、私が何をする必要があるかを言葉で表現できるかどうか見てみましょう。

タイムレコーダーから*を選択し、user.parentcompany_idに参加する必要があります。ここで、timeclock.daydate <:startおよびここでu.parentcompany =:pid

ここで、startは次のとおりです。 `date('Ymd 00:00:00');

私はこのクエリを設定しました:

$em = $this->getDoctrine()->getEntityManager();
$start = date('Y-m-d 00:00:00');
$qb = $em->getRepository('EcsCrmBundle:TimeClock');
$qb = $qb->createQueryBuilder('t');

$query = $qb->select('t, u.parentcompany_id')
->from('timeclock', 't')
->leftJoin('Ecs\AgentManagerBundle\Entity\User', 'u', 'ON' 'u.id = t.noteBy_id AND u.parentcompany_id = :pid')
->where('t.daydate < :start')
->andWhere("t.noteBy_id != ''")
->setParameter('start', $start)
->setParameter('pid', $user->getParentcompany())
->getQuery();

$entities = $query->getArrayResult();

私は調べてみましたが、私が得るエラーの解決策を見つけることができません:それは次のとおりです:

An exception has been thrown during the rendering of a template ("[Semantical Error] line 0, col 112 near 'u ON u.id = t.noteBy_id': Error: Identification Variable Ecs\AgentManagerBundle\Entity\User used in join path expression but was not defined before.") in EcsCrmBundle:TimeClock:manager.html.twig at line 5.

出力を取得するクエリは次のとおりです。

SELECT t, u.parentcompany_id FROM Ecs\CrmBundle\Entity\TimeClock t LEFT JOIN Ecs\AgentManagerBundle\Entity\User u ON u.id = t.noteBy_id AND u.parentcompany_id = :pid, timeclock t LEFT JOIN Ecs\AgentManagerBundle\Entity\User u ON u.id = t.noteBy_id AND u.parentcompany_id = :pid WHERE t.daydate < :start AND t.noteBy_id != ''

これは通常の状況では完全に機能します...しかし、これでは機能しません...何かアイデアはありますか?

4

2 に答える 2

3

最近、このようにする必要がありました。これで、noteByはユーザーテーブルのManyToOneであり、現在ログインしている管理者の会社によって結果をフィルタリングする必要があると推測しています。システム..

だから、私がそのようなタスクのために自分で書かなければならなかった結合を適応させることは十分に簡単です。私は個人的にQueryBuilderを使用するのが好きなので、これはクエリビルダーで行われます。

クエリの最初の間違いは->from('timeclock', 't')行です。以前にオブジェクトを作成したことがあるため、クエリビルダーでオブジェクトが生成されるため、オブジェクト$qb = $em->getRepository('EcsCrmBundle:TimeClock'); $qb = $qb->createQueryBuilder('t');は必要ありません。from

次の問題はleftJoinで、動作するバージョンを示したときにその理由を説明します。

そして最後の問題は、これがあなたが望むように機能するのを妨げることです-欠落しているandWhere節です。それでは、実際のクエリを見てみましょう。

$query = $qb->select('t, u')
     ->leftJoin('t.noteBy', 'u', 'WITH', 'u.id = t.noteBy')
     ->where('t.daydate < :start')
     ->andWhere('u.parentcompany = :pid')
     ->setParameter('start', $start)
     ->setParameter('pid', $user->getParentcompany()) 
     ->getQuery();

を使用してオブジェクトをすでに作成しているので、$qb = $qb->createQueryBuilder('t')選択tしてu

結合では、タイムクロックテーブルをnoteBy列で結合します。これは、ユーザーテーブルのユーザーIDです。したがって、最初の引数は「from」エイリアスです。したがって、タイムクロックテーブルをtでエイリアス化したので、を使用しますt.noteBy。leftjoinの次の引数は、2番目のテーブルのエイリアスuです。この場合は、何でもかまいません。とにかく、leftJoinの3番目の引数は、結合する方法です。またはは、WITHここONで機能します。そして4番目の引数はあなたが望むマッチです..この場合u.id must equal t.noteBy

適切に構造化されたクエリをandWhere使用すれば必要ないため、これを実行しました。andWhereただし、私はforを追加しました。これu.parentcompanyは、結局のところ、フィルタリングしようとしているものは、結合自体の一致としてではなく、WHEREに含める必要があるためです。

ドキュメントはこれで非常に限られており、それをすべて理解するのにも時間がかかりました。間違いなく、私のように、手でクエリを書くことから教義を使用するようになりました。そして、あなたはSymfonyを始めたばかりのようです(私も今から約2か月です)ので、あなたはまだハンドコーディングの考え方を持っています。しかし、時間が経つにつれて、DQLの生き方を理解し始めるでしょう。このクエリを試して、何が起こるかを確認してください。

于 2012-04-05T02:08:01.980 に答える
0

わかりました。まず、エンティティTimeclockをに関連付ける必要がありますCompany。2つのエンティティを結合する場合は常にDoctrine、何らかの属性(つまり、テーブル列)によって関連付ける必要があります。

Userすべての情報はCompanyエンティティを通じて利用可能であり、ユーザープロパティに基づいて結果をフィルタリングしていないため、このクエリにはエンティティの必要性はありません。

希望するクエリは次のようになります(多かれ少なかれ)。_id実際に起こっていることを曇らせる傾向があるので、エンティティ属性から自由と捨てられた接尾辞を取りました。;)

$query = $this->getEntityManager()->createQuery("SELECT t, c.id FROM EcsCrmBundle:TimeClock t JOIN t.company c WHERE c.id = :pid AND t.daydate < :start AND t.noteBy != ''");

$query->setParameter('start', $start);
$query->setParameter('pid', $user->getParentcompany());
return $query->getArrayResult();

また、会社なしではタイムレコーダーはあり得ないと思うのでinner-join( )しましたが、よろしければお気軽に変更してください。JOINLEFT JOIN

これはあなたが達成しようとしていたことですか?

于 2012-04-04T23:36:08.903 に答える