改进自关联查询多级调用问题

This commit is contained in:
thinkphp
2018-01-05 17:28:21 +08:00
parent 1f06d05cbe
commit ea2ce8f8de
4 changed files with 34 additions and 23 deletions

View File

@@ -192,7 +192,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$con = Db::connect($connection); $con = Db::connect($connection);
// 设置当前模型 确保查询返回模型对象 // 设置当前模型 确保查询返回模型对象
$queryClass = $this->query ?: $con->getConfig('query'); $queryClass = $this->query ?: $con->getConfig('query');
$query = new $queryClass($con, $this->class); $query = new $queryClass($con, $this);
// 设置当前数据表和模型名 // 设置当前数据表和模型名
if (!empty($this->table)) { if (!empty($this->table)) {
@@ -208,6 +208,19 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
return $query; return $query;
} }
/**
* 创建新的模型实例
* @access public
* @param array|object $data 数据
* @param bool $isUpdate 是否为更新
* @param mixed $where 更新条件
* @return Model
*/
public function newInstance($data = [], $isUpdate = false, $where = null)
{
return (new static($data))->isUpdate($isUpdate, $where);
}
/** /**
* 获取当前模型的查询对象 * 获取当前模型的查询对象
* @access public * @access public
@@ -599,7 +612,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/ */
protected function getRelationData(Relation $modelRelation) protected function getRelationData(Relation $modelRelation)
{ {
if ($this->parent && get_class($this->parent) == $modelRelation->getModel()) { if ($this->parent && $modelRelation->getModel() == $this->parent) {
$value = $this->parent; $value = $this->parent;
} else { } else {
// 首先获取关联数据 // 首先获取关联数据

View File

@@ -58,9 +58,9 @@ class Query
* 构造函数 * 构造函数
* @access public * @access public
* @param Connection $connection 数据库对象实例 * @param Connection $connection 数据库对象实例
* @param string $model 模型 * @param Model $model 模型对象
*/ */
public function __construct(Connection $connection = null, $model = '') public function __construct(Connection $connection = null, $model = null)
{ {
$this->connection = $connection ?: Db::connect([], true); $this->connection = $connection ?: Db::connect([], true);
$this->prefix = $this->connection->getConfig('prefix'); $this->prefix = $this->connection->getConfig('prefix');
@@ -133,7 +133,7 @@ class Query
/** /**
* 获取当前的模型对象名 * 获取当前的模型对象名
* @access public * @access public
* @return string * @return Model|null
*/ */
public function getModel() public function getModel()
{ {
@@ -1910,11 +1910,10 @@ class Query
$with = explode(',', $with); $with = explode(',', $with);
} }
$first = true; $first = true;
$currentModel = $this->model;
/** @var Model $class */ /** @var Model $class */
$class = new $currentModel; $class = $this->model;
foreach ($with as $key => $relation) { foreach ($with as $key => $relation) {
$subRelation = ''; $subRelation = '';
$closure = false; $closure = false;
@@ -1973,7 +1972,7 @@ class Query
$relation = $key; $relation = $key;
} }
$relation = Loader::parseName($relation, 1, false); $relation = Loader::parseName($relation, 1, false);
$count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')'; $count = '(' . $this->model->$relation()->getRelationCountQuery($closure) . ')';
$this->field([$count => Loader::parseName($relation) . '_count']); $this->field([$count => Loader::parseName($relation) . '_count']);
} }
} }
@@ -2365,11 +2364,10 @@ class Query
// 数据列表读取后的处理 // 数据列表读取后的处理
if (!empty($this->model)) { if (!empty($this->model)) {
// 生成模型对象 // 生成模型对象
$modelName = $this->model;
if (count($resultSet) > 0) { if (count($resultSet) > 0) {
foreach ($resultSet as $key => $result) { foreach ($resultSet as $key => $result) {
/** @var Model $model */ /** @var Model $model */
$model = new $modelName($result); $model = $this->model->newInstance($result);
$model->isUpdate(true); $model->isUpdate(true);
// 关联查询 // 关联查询
@@ -2389,7 +2387,7 @@ class Query
// 模型数据集转换 // 模型数据集转换
$resultSet = $model->toCollection($resultSet); $resultSet = $model->toCollection($resultSet);
} else { } else {
$resultSet = (new $modelName)->toCollection($resultSet); $resultSet = $this->model->toCollection($resultSet);
} }
} elseif ('collection' == $this->connection->getConfig('resultset_type')) { } elseif ('collection' == $this->connection->getConfig('resultset_type')) {
// 返回Collection对象 // 返回Collection对象
@@ -2525,8 +2523,7 @@ class Query
if (!empty($result)) { if (!empty($result)) {
if (!empty($this->model)) { if (!empty($this->model)) {
// 返回模型对象 // 返回模型对象
$model = $this->model; $result = $this->model->newInstance($result);
$result = new $model($result);
$result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); $result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null);
// 关联查询 // 关联查询
if (!empty($options['relation'])) { if (!empty($options['relation'])) {
@@ -2557,7 +2554,8 @@ class Query
protected function throwNotFound($options = []) protected function throwNotFound($options = [])
{ {
if (!empty($this->model)) { if (!empty($this->model)) {
throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options); $class = get_class($this->model);
throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options);
} else { } else {
$table = is_array($options['table']) ? key($options['table']) : $options['table']; $table = is_array($options['table']) ? key($options['table']) : $options['table'];
throw new DataNotFoundException('table data not Found:' . $table, $table, $options); throw new DataNotFoundException('table data not Found:' . $table, $table, $options);

View File

@@ -49,11 +49,11 @@ abstract class Relation
/** /**
* 获取当前的关联模型类 * 获取当前的关联模型类
* @access public * @access public
* @return string * @return Model
*/ */
public function getModel() public function getModel()
{ {
return $this->model; return $this->query->getModel();
} }
/** /**

View File

@@ -57,18 +57,18 @@ abstract class OneToOne extends Relation
*/ */
public function eagerly(Query $query, $relation, $subRelation, $closure, $first) public function eagerly(Query $query, $relation, $subRelation, $closure, $first)
{ {
$name = Loader::parseName(basename(str_replace('\\', '/', $query->getModel()))); $name = Loader::parseName(basename(str_replace('\\', '/', get_class($query->getModel()))));
$alias = $name;
if ($first) { if ($first) {
$table = $query->getTable(); $table = $query->getTable();
$query->table([$table => $alias]); $query->table([$table => $name]);
if ($query->getOptions('field')) { if ($query->getOptions('field')) {
$field = $query->getOptions('field'); $field = $query->getOptions('field');
$query->removeOption('field'); $query->removeOption('field');
} else { } else {
$field = true; $field = true;
} }
$query->field($field, false, $table, $alias); $query->field($field, false, $table, $name);
$field = null; $field = null;
} }
@@ -78,9 +78,9 @@ abstract class OneToOne extends Relation
$query->via($joinAlias); $query->via($joinAlias);
if ($this instanceof BelongsTo) { if ($this instanceof BelongsTo) {
$query->join([$joinTable => $joinAlias], $alias . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); $query->join([$joinTable => $joinAlias], $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType);
} else { } else {
$query->join([$joinTable => $joinAlias], $alias . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); $query->join([$joinTable => $joinAlias], $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType);
} }
if ($closure) { if ($closure) {