您如何使用Eloquent在两个表之外的另一个数据库中查找相关值?

时间:2019-04-16 14:19:46

标签: laravel eloquent

我正在开发一个扩展现有ERP系统的系统,因此正在访问两个数据库(都在同一MS SQL Server上)。我试图通过“ EquipmentType”模型(这两个在新数据库中)通过“ EquipmentInstance”模型访问“ Equipment”模型(这是ERP数据库中的表)上的项目。它们根据此图相关:

ER diagram depicting relationship

这三个模型如下:

设备类型

namespace App;

use Illuminate\Database\Eloquent\Model;

class EquipmentType extends Model
{
    protected $table = 'dbo.EquipmentType';
    protected $connection = 'sqlsrv';
    protected $primaryKey = 'EquipmentTypeID';
    protected $fillable = [
        'TypeName',
        'ProductManager'
        ];

    public function EquipmentInstance()
    {
        return $this->hasMany(EquipmentInstance::class,'EquipmentTypeID', 'EquipmentTypeID');
    }

    public function Equipment()
    {
        return $this->hasManyThrough(
            Equipment::class,
            EquipmentInstance::class,
            'TypeID',
            'PartNum',
            'TypeID',
            'PartNum'
        );
    }
}

EquipmentInstance

namespace App;

use Illuminate\Database\Eloquent\Model;

class EquipmentInstance extends Model
{
    protected $table = 'dbo.EquipmentInstance';
    protected $primaryKey = 'EquipmentID';
    protected $keyType = 'string';
    protected $connection = 'sqlsrv';
    protected $fillable = [
        'EquipmentID',
        'EquipmentTypeID',
        'PartNum'
    ];

    public function Part()
    {
        return $this->belongsTo(Part::class,'PartNum','PartNum');
    }

    public function Equipment()
    {
        return $this->hasMany(Equipment::class,'PartNum', 'PartNum');
    }

    public function EquipmentType()
    {
        return $this->belongsTo(EquipmentType::class); /*,'EquipmentTypeID', 'EquipmentTypeID'*/
    }


/*    public function Attribute()
    {
        return $this->belongsTo(Equipment::class,'SerialNumber', 'JobNum');
    }

    public function TechNote()
    {
        return $this->belongsTo(Equipment::class,'SerialNumber', 'JobNum');
    }*/

}

设备

namespace App;

use Illuminate\Database\Eloquent\Model;

class Equipment extends Model
{
    protected $table = 'ERP.SerialNo';
    public $timestamps = false;
    protected $primaryKey = 'SerialNumber';
    protected $keyType = 'string';
    protected $connection = 'epicor';


    public function Part()
    {
        return $this->belongsTo(Part::class,'PartNum','PartNum');
    }

    public function Customer()
    {
        return $this->belongsTo(Customer::class,'CustNum', 'CustNum');
    }

    public function Equipment()
    {
        return $this->belongsTo(Equipment::class,'SerialNumber', 'JobNum');
    }

    public function EquipmentInstance()
    {
        return $this->belongsTo(EquipmentInstance::class,'PartNum', 'PartNum');
    }
}

在EquipmentType控制器上,我试图通过EquipmentInstance获得所有设备,因此对于每个EquipmentInstance,我可以显示所有Equipment。

设备类型控制器

public function show(EquipmentType $EquipmentType)
{
    $EquipmentInstance = $EquipmentType->EquipmentInstance()
        ->get();

    $Equipments = $EquipmentType->EquipmentInstance()->Equipment()
        ->get();

    return view('EquipmentType.show', compact('EquipmentType', 'EquipmentInstance', 'Equipments'));

}

我收到的错误消息是

"BadMethodCallException
Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::Equipment()"

我相信问题是(据我的理解是艰难的),Eloquent试图编写一个查询来访问两个数据库,但都失败了。但是我不确定如何进行。

任何帮助都会得到很大的帮助。

理查德

更新

我已经执行了gbalduzzi在他的回答中提出的建议,该建议几乎奏效了,并且我确信问题出在我的刀片无用。我嵌套了两个forloops:

@foreach($EquipmentType->EquipmentInstance as $EquipmentInstance)
    @foreach($Equipments as $Equipment)
        <tr>
        <td>{{$EquipmentInstance->PartNum}} - {{$EquipmentInstance->Part->PartDescription}}</td>
         <td><a href="">{{$Equipment->SerialNumber}}</a></td>
         <td>{{$Equipment->SNStatus}}</td>
         <td>{{--{{$Equipment->Customer->LegalName}}--}}</td>
         </tr>
    @endforeach
@endforeach 

仅显示第一个EquipmentInstance的序列号(来自Equipment模型),并为所有EquipmentInstanced重复序列号。

更新2

我已经证明问题在于建议的答案中的first(),就好像我将其更改为last()一样,结果也按您期望的那样更改(请参阅更新1)。所以我的问题是:

是否存在all()或every()的first(),last()等价物?

1 个答案:

答案 0 :(得分:1)

问题不在于您的数据库配置,而在于您调用关系的方式。代替:

$Equipments = $EquipmentType->EquipmentInstance()->Equipment()
    ->get();

使用:

$Equipments = $EquipmentType->EquipmentInstance->first()->Equipment()
    ->get();

好答案

在雄辩的语言中,您可以通过两种方式使用关系:

  • 作为魔术场(即$EquipmentType->EquipmentInstance)。在这种情况下,您将得到模型EquipmentInstance的实例(此外,如果您已经查询过,它会直接返回值,而无需执行新查询)

  • 作为雄辩的查询(即$EquipmentType->EquipmentInstance())。使用它作为函数,您不会得到模型,而只是得到一个RelationShip实例,该实例基本上是一个雄辩的查询,并且可以与其他雄辩的方法(例如,whereorderBy)链接在一起,ecc

因此,如果您调用$EquipmentType->EquipmentInstance()->Equipment()会引发错误,因为雄辩的查询不具有关系Equipment()

另一方面,$EquipmentType->EquipmentInstance->Equipment之所以起作用,是因为它在具有正确定义的Equipment关系的实际模型实例上调用Equipment