使 Laravel 模型使用复杂查询作为 table

Making a Laravel Model use complex query as table

我正在开发一个与 ERP 生产数据库接口的 Web 应用程序,数据正在通过复杂的 SQL 查询检索,该查询具有许多连接和别名,然后再传递到我的控制器和视图中修改它们不同的方法。

例如,结果可能是一组产品,其中包含每次购买的所有相关信息,例如型号、序列号、客户等,在较小规模的应用程序中,这些肯定都会存储在同样的 table.

然而,因为我是从一个非常复杂的 ERP 解决方案中提取的,所以这些细节取自许多不同的 table,但我想在我的模型中将其视为单个 table。

有什么办法可以做到这一点,这样我就可以像往常一样使用 Eloquent 了吗? Product::all() 之类的东西不起作用,尽管我可以调用 Product::getWhere($serial) 之类的自定义方法,但我宁愿以 Eloquent 方式执行此操作,因为它更容易并且使分页更好用。

以下是我的查询的大致思路:

SELECT
[PSerials].[ElementID] AS [ProductElementID],
[PSerials].[SerialNumber] AS [SerialNumber],
[PSerials].[SNStatus] as [ProductStatus],
[PSerials].[JobID] AS [JobID],
[Element].[Desc] AS [Description],
[PSerials_UD].[Prog] AS [ProgramNum],
[PSerials_UD].[Elec] AS [ElecPrint],
[PSerials_UD].[SinglePHVolt_c] AS [SinglePHVolt],
[PSerials_UD].[SinglePHAmp_c] AS [SinglePHAmp],
[PSerials_UD].[ThreePHVolt_c] AS [ThreePHVolt],
[PSerials_UD].[ThreePHAmp_c] AS [ThreePHAmp],
[PSerials_UD].[Notes_c] AS [Notes],
[PSerials_UD].[WarrantyExpDate_c] AS [WarrantyExpDate],
[QuoteDtl].[QuoteNum] AS [QuoteNum],
[QuoteDtl].[QuoteComment] AS [QuoteComment],
[OrderDtl].[RequestDate] AS [ShipDate],
[Customer].[CustID] AS [CustomerID],
[Customer].[Name] AS [CustomerName],
[Customer1].[CustID] AS [ShipToCustomerID],
[Customer1].[Name] AS [ShipToCustomerName]
FROM Erp.PSerials AS PSerials
INNER JOIN Erp.Element AS Element ON
PSerials.Company = Element.Company AND PSerials.ElementID = Element.ElementID
AND (Element.ProdCode = 'MACH' AND Element.ClassID = 'MAC')
INNER JOIN Erp.PSerials_UD AS PSerials_UD ON
PSerials_UD.ForeignSysRowID = PSerials.SysRowID
LEFT OUTER JOIN Erp.PProd AS PProd ON PProd.JobID = PSerials.JobID
LEFT OUTER JOIN Erp.OrderDtl AS OrderDtl ON PProd.Company = OrderDtl.Company
AND PProd.OrderNum = OrderDtl.OrderNum AND PProd.OrderLine = OrderDtl.OrderLine
LEFT OUTER JOIN Erp.QuoteDtl AS QuoteDtl ON OrderDtl.QuoteNum = QuoteDtl.QuoteNum
AND OrderDtl.QuoteLine = QuoteDtl.QuoteLine
LEFT OUTER JOIN Erp.Customer AS Customer ON  OrderDtl.Company = Customer.Company
AND OrderDtl.CustNum = Customer.CustNum
LEFT OUTER JOIN Erp.Customer AS Customer1 ON PSerials.Company = Customer1.Company
AND PSerials.ShipToCustNum = Customer1.CustNum

我把它放在我的 Product 模型的一个静态变量中,然后有自定义函数,可以根据需要简单地将 SQL 查询添加到最后,但这并不优雅而且它使用起来并不有趣,这是我如何使用这些查询的示例:

public static function getWhere($serial)
{
    $query = DB::select(DB::raw(Self::$baseQuery));
    $collection = new \Illuminate\Support\Collection($query);

    $product = $collection->where("SerialNumber", $serial)->first();

    return $product;
}

有没有人知道如何让我的模型像简单的查询一样简单地处理查询 table,或者是否有其他方法可以做到这一点?

更新

感谢 Zamrony P. Juhara 在下面的建议,我能够成功创建一个 SQL 视图并告诉我的产品模型参考就像 table:

class Product extends Model
{
    protected $table = 'dbo.ProductInfo';
}

现在 Product::all() 按预期工作。

关于 Peh 指出的限制,此应用程序纯粹用于查看 ERP 软件中存在的数据,不需要更新或删除任何记录,因此在这种情况下 SQL 视图是绝对完美。

您可以将 SQL 命令转换为 VIEW (CREATE VIEW),然后在您的模型中像普通 table 一样使用它。