使 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 一样使用它。
我正在开发一个与 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 一样使用它。