將 SP 加入 EDM 後,於模型瀏覽器執行「加入函數導入」,對應回傳實體集合。EDMX 三層呈現:
<Function Name="GetOrder" ...><Parameter Name="OrderID" Type="int" Mode="In" /></Function><FunctionImport Name="GetOrders" EntitySet="Orders" ReturnType="Collection(NorthwindModel.Orders)">...</FunctionImport><FunctionImportMapping FunctionImportName="GetOrders" FunctionName="Store.GetOrder" />呼叫:context.GetOrders(10248).First()。
適用於不想建立 SP、或需動態 SQL 的場景。
<Function Name="CustomerWithHighestSales" ...>
<CommandText>
SELECT * FROM Customers
WHERE CustomerID = (
SELECT TOP 1 o.CustomerID FROM Orders o
JOIN OrderDetails od ON o.OrderID = od.OrderID
GROUP BY o.CustomerID
ORDER BY SUM(od.UnitPrice * od.Quantity) DESC
)
</CommandText>
</Function>
CSDL/MSL 對應方式相同,呼叫介面無差異。
EDM 設計器會忽略含 Output 參數的 SP。需手動編輯 EDMX:
<!-- SSDL -->
<Function Name="GetTotalOrdersForCust" ...>
<Parameter Name="CustomerID" Type="nchar" Mode="In" />
<Parameter Name="Count" Type="int" Mode="InOut" />
</Function>
<!-- CSDL -->
<FunctionImport Name="GetTotalOrdersForCust">
<Parameter Name="CustomerID" Type="String" Mode="In" />
<Parameter Name="Count" Type="Int32" Mode="InOut" />
</FunctionImport>
呼叫端手工構建 DbCommand:
public void GetTotalOrdersForCust(string customerId, out int total)
{
var cmd = this.Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = this.DefaultContainerName + ".GetTotalOrdersForCust";
cmd.Parameters.Add(new EntityParameter("CustomerID", DbType.String) { Value = customerId });
var outParam = new EntityParameter("Count", DbType.Int32) { Direction = ParameterDirection.Output };
cmd.Parameters.Add(outParam);
if (cmd.Connection.State == ConnectionState.Closed) cmd.Connection.Open();
cmd.ExecuteNonQuery();
total = (int)outParam.Value;
}
EF Core 後續版本已原生支援 Output 參數,舊專案可採此手動映射過渡。