Symfony2-实体中的Access存储库功能 [英] Symfony2 - Access repository functions in Entity

查看:68
本文介绍了Symfony2-实体中的Access存储库功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的数据库中有两个表:Rabbits和Carrots。
兔子可以有0个或多个胡萝卜,并且胡萝卜属于单个兔子。那是这两个表之间的1,n关系。



那么我有两个实体,兔子和胡萝卜。



我在模板中传递了一系列兔子,我想从每只兔子中获取特定的胡萝卜并进行展示:假设我想从每只兔子中获取10支更昂贵的胡萝卜(胡萝卜价格将存储在胡萝卜表中)

类似的东西:

  {%兔子中的兔子%} 
{%兔子中的胡萝卜%.getMoreExpensiveCarrots%}

{{胡萝卜。价格}}

{%endfor%}
{%endfor%}

我正在使用存储库类,但是如果我创建一个函数getMoreExpensiveCarrots ($ rabbit)在Rabbit仓库类中,我将无法从这样的实体类中访问该功能,这就是我想要的:



$ rabbit- > getMoreExpensiveCarrots()



我认为做到这一点的一种方法是增加在兔子实体中获取getMoreExpensiveCarrots():

  //实体兔子
类Rabbit
{
公共函数getMoreExpensiveCarrots()
{
//访问诸如getMoreExpensiveCarrots($ rabbit)
这样的存储库函数但是我该怎么做?那不是不好的做法吗?
返回$胡萝卜;
}
}

我想我也可以做到:

  //实体Rabbit 
类Rabbit
{
public function getMoreExpensiveCarrots()
{
$ this-> getCarrots();

//然后尝试在此处按胡萝卜的价格对胡萝卜进行排序,使用php

return $ carrots;
}
}

这是我的控制者:

 公共功能indexAction()
{
$ em = $ this-> getDoctrine()-> getEntityManager();

$ rabbits = $ em-> getRepository(’AppNameBundle:Rabbit’)-> getSomeRabbits();

返回$ this-&r; render('AppNameBundle:Home:index.html.twig',
array(
rabbits => $ rabbits
));
}

从模板中的每只兔子调用getMoreExpensiveCarrots函数的最佳实践是什么



谢谢!

解决方案

回到基础知识。忘了存储库与服务的关系,而只关注兔子和胡萝卜。

  class Rabbit 
{
/ * * @ ORM\OneToMany(targetEntity = Carrot,mappingBy = rabbit * /
受保护的$ carrots;

公共函数getCarrots(){return $ this->胡萝卜; }

公共函数getMoreExpensiveCarrots()
{
//获取所有胡萝卜
$ carrots = $ this-> getCarrots()-totoArray();

//按价格
// http://php.net/manual/en/function.usort.php
usort(& $ carrots,array($ this,'compareTwoCarrotsByPrice'));

//现在将前10个胡萝卜切成薄片(切片-胡萝卜,哈哈,有趣的
$ carrots = array_slice($ carrots,0,10 );

//返回经过排序的胡萝卜
return $ carrots;
}
公共函数compareTwoCarrotsByPrice($ carrot1,$ carrot2)
{
if($ carrot1-> getPrice()> $ carrot2-> getPrice())返回-1;
if($ carrot1-> getPrice()< ; $ carrot2-> getPrice())返回1;
返回0;
}
}

从查询中删除所有胡萝卜内容,然后获取

您的原始模板现在将完全按预期工作:

  {%for rabbit在兔子中%} 
{%在rabbit.getMoreExpensiveCarrots%}中

{{胡萝卜。价格}}

{%endfor%}
{%endfor%}

这里唯一的缺点是每只兔子都单独查询所有胡萝卜将由教义自动生成。在某些时候,性能会受到阻碍。当达到这一点时,您可以返回到原始查询,并查看如何更有效地引入胡萝卜。但是首先让上述课程开始工作,因为我认为这可能是您的阻碍点。


Let's say that I have two tables in my database : Rabbits and Carrots. Rabbits can have 0 or multiples carrots and a carrot belongs to a single rabbit. That's a 1,n relation between those two tables.

I have then two entities, rabbit and carrot.

I have an array of rabbits passed in my template and I would like to get specific carrots from each rabbit an display them : let's say I want to get the 10 more expensive carrots (carrots prices would be stored in the carrots table) from each $rabbit in the array.

Something like :

{% for rabbit in rabbits %}
    {% for carrot in rabbit.getMoreExpensiveCarrots %}

        {{ carrot.price }}

    {% endfor %}
{% endfor %}

I'm using repository class, but if i create a function getMoreExpensiveCarrots( $rabbit ) in a rabbit repository class, I would not be able to access that function from an entity class like that, which is what I want :

$rabbit->getMoreExpensiveCarrots()

I thought that a way to do that would be to create a getMoreExpensiveCarrots() in the rabbit entity :

// Entity rabbit
class Rabbit
{
    public function getMoreExpensiveCarrots()
    {
        // Access repository functions like getMoreExpensiveCarrots( $rabbit )
        // But how can I do such thing ? Isn't that bad practise ?
        return $carrots;
    }         
}

I thought I could do that too :

    // Entity rabbit
    class Rabbit
    {
        public function getMoreExpensiveCarrots()
        {
            $this->getCarrots();

            // Then try here to sort the carrots by their price, using php            

            return $carrots;
        }         
    }

Here is my controller :

    public function indexAction()
    {
        $em = $this->getDoctrine()->getEntityManager();

        $rabbits = $em->getRepository('AppNameBundle:Rabbit')->getSomeRabbits();

        return $this->render('AppNameBundle:Home:index.html.twig', 
                array(
                    "rabbits"=>$rabbits
        ));
    }

What is the best practise to call a getMoreExpensiveCarrots function from each rabbit in the template ?

Thanks!

解决方案

Back to basics. Forget about repository vs service and just focus on rabbits and carrots.

class Rabbit
{
/** @ORM\OneToMany(targetEntity="Carrot", mappedBy="rabbit" */
protected $carrots;

public function getCarrots() { return $this->carrots; }

public function getMoreExpensiveCarrots()
{
    // Get all carrots
    $carrots = $this->getCarrots()->toArray();

    // Sort by price
    // http://php.net/manual/en/function.usort.php
    usort(&$carrots,array($this,'compareTwoCarrotsByPrice'));

    // Now slice off the top 10 carrots (slice - carrots, hah, kindo of funny
    $carrots = array_slice($carrots, 0, 10);

    // And return the sorted carrots
    return $carrots;
}
public function compareTwoCarrotsByPrice($carrot1,$carrot2)
{
    if ($carrot1->getPrice() > $carrot2->getPrice()) return -1;
    if ($carrot1->getPrice() < $carrot2->getPrice()) return  1;
    return 0;
}
}

Remove all the carrot stuff from your query and just get a list of rabbits.
Your original template will now work exactly as expected:

{% for rabbit in rabbits %}
    {% for carrot in rabbit.getMoreExpensiveCarrots %}

        {{ carrot.price }}

    {% endfor %}
{% endfor %}

The only downside here is that for each rabbit, a separate query for all carrots will be automatically generated by Doctrine. At some point performance will be hindered. When you reach that point then you can go back to your original query and see how to bring the carrots in more efficiently. But get the above class working first as I think this might be your blocking point.

这篇关于Symfony2-实体中的Access存储库功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆