学说单表继承保存Findall



我在尝试使用教义单表继承时有一个很大的问题。

我有一个Division实体,该实体代表地理区域(城市,县,国家,地区或任何特定国家/地区的行政部门)。为了满足我的应用需求,我需要特别识别具有City实体的城市。我认为,城市是世界上广泛共享的行政领域,这是有道理的。

这是我基本上是想要的:

class Division {
    /** @var boolean */
    protected $city;
}

class City extends Division {
    /** @var boolean */
    protected $city = true;
}

两个是共享同一表的学说实体。

使用存储库,我希望能够获得此行为:

// return counties, regions, AND cities but all mapped to Division class
$divisionsRepositories->findAll();
// return only cities, mapped to City class
$citiesRepositories->findAll();
// if id #12 is a division with $city = false, returns null
$citiesRepositories->find(12);
// persist to divisions table a row with city = 1
$citiesRepositories->persist(new City("Paris"));

我已经与歧视者一起玩了很多,但是由于歧视者迫使我为部门实体做出独特的选择(因此,查询总是会得到city IN ('0')),因此找不到一种方法来获得这一结果。我什至尝试创建一个" LoadClassMetadata"事件的侦听器,以覆盖元数据,但它会损坏很多东西。

在提出"为什么"问题的情况下:类型,更准确的相关实体关系,特定的存储库(以及更好的di)...很多原因!

关于如何用学说重现这一点的任何想法?看起来很简单,以至于我发疯了!

[编辑]这是我按照评论中要求的(

)尝试的(一种)歧视词。

/**
 * @ORMTable(name="divisions")
 * @ORMInheritanceType("SINGLE_TABLE")
 * @ORMEntity()
 * @ORMDiscriminatorColumn(name="city", type="integer")
 * @ORMDiscriminatorMap({
 *     0 = "Division",
 *     1 = "Division",
 *     1 = "City"
 * })
 */
abstract class AbstractDivision

您不能这样做。我们在学说文档中有@DiscriminatorMap说明:

IncriminatorMap的关键是数据库值,值是类。

因此,如果您将两个类设置为数据库值,那么学说将如何返回将city=1列作为城市或部门的行?

学说的工作方式:

/**
 * @ORMTable(name="divisions")
 * @ORMInheritanceType("SINGLE_TABLE")
 * @ORMEntity()
 * @ORMDiscriminatorColumn(name="city", type="integer")
 * @ORMDiscriminatorMap({
 *     0 = "Division",
 *     1 = "City"
 * })
 */
abstract class Division
// return Division and it subclasses but all mapped to their repectives classes
$divisionsRepositories->findAll();
// return only cities, mapped to City class
$citiesRepositories->findAll();
// if id #12 is a Division instance (city = false), returns null
$citiesRepositories->find(12);
// persist to divisions table a row with city = 1
$citiesRepositories->persist(new City("Paris"));

因此,几乎所有事情都像您预期的那样工作。第一种情况,$divisionsRepositories->findAll()这是这里唯一的问题。但是,如果您仔细看,不是因为:

//if $divisions returns for instance an array [City, Division]
$divisions = $divisionsRepositories->findAll();
// City instance
$city =  $division[0];
// Division instance
$division = $division[1];
echo $city instanceof City; // true, outputs 1
echo $city instanceof Division; // true, outputs also 1
echo $division instanceof City; // false, outputs empty
echo $division instanceof Division; // true, outputs 1

编辑

我发现的关于您的问题和地雷工作的唯一区别是:我没有使用抽象类。因此,划分将具有所有注释,并且将删除摘要。

关于查询构建器中的过滤器,仅返回城市或部门。您应该添加"实例",例如:

 //$qb as a QueryBuilder instance, to returns only instances of City
 $qb->from('ApiBundleEntityGeographyDivision','d');
 $qb->andWhere('d INSTANCE OF ApiBundleEntityGeographyCity');

您需要为子实体定义至少一个存储库,并覆盖Findall并找到方法以实现您上述内容。

相关内容

  • 没有找到相关文章

最新更新