【发布时间】:2012-03-28 07:16:50
【问题描述】:
我想在 edmx 中创建一个函数,它返回缩放器值, 如何在 SSDL 中创建它以及如何在代码中访问它?
【问题讨论】:
-
我在 ssdl 中添加
标记,其中在 部分定义我的 sql 查询并将其设置为 iscomposable = true 但它不起作用,我只希望我的表中的产品名称基于产品编号,
标签: entity-framework linq-to-entities edmx
我想在 edmx 中创建一个函数,它返回缩放器值, 如何在 SSDL 中创建它以及如何在代码中访问它?
【问题讨论】:
标签: entity-framework linq-to-entities edmx
您遇到的一个问题是您的 SSDL 是由“EntityModelGenerator”自动生成的,因此对其进行编辑将被重建所清除。您需要在 EDMX 文件中进行编辑。
因此,首先,您必须确定 (1) 您的返回值是一种排序计算(即在应用程序中将值相加,而不是在数据库级别),或者 (2) 是否直接调用存储的数据库流程?
(1) 第一步是将函数 XML 定义添加到您的 EDMX 文件中:
<Function Name="LineTotal" ReturnType="decimal">
<Parameter Name="lineTotal" Type="MyDbModel.OrderDetail">
<DefiningExpression>
od.Price * od.Quantity
</DefiningExpression>
</Parameter>
</Function>
现在,虽然您的 EDMX 知道此功能,但您的 IntelliSense 不会。因此,您必须添加一些代码才能使其正常工作。最好将这些函数放在一个单独的类中。
public class ModelDefinedFunctions
{
[EdmFunction("MyDbModel" , "LineTotal")] //Model Name and Function Name
public static decimal LineTotal(OrderDetail od)
{
throw new NotSupportedException("LineTotal cannot be directly used.");
}
}
Entity Framework 将知道将此函数调用重定向到 EDMX。任何对该方法的直接调用,如果模型不存在,都会抛出异常。
然后您可以在 LINQ 查询中调用它,例如
var productValues = from line in model.OrderDetails
select new
{
od.ProductID,
od.Price,
od.Quantity,
LineTotal = ModeDefinedFunctions.LineTotal(line)
};
(2) 如果直接添加存储过程,将其拖放到 EDMX 设计器上会更容易。有一个 [FunctionImport()] 属性,但我没有使用它。可以拖放看看它在EDMX文件中生成了什么代码?
也可以调用model.ExecuteCommand(<spname> , params object[] values
)存储过程执行方法。
【讨论】: