关于实体框架实体中自定义扩展属性的另一个问题。
实体模型一般来说非常简单。当然实际上它更复杂,但仅仅是因为我没有粘贴所有生成的代码,只是类和所需的属性。 所以,我有实体类:
partial class Calibration
{
public string Identifier {get;set;}
public Device CalibratedDevice {get;set;}
}
partial class Device
{
public string Name {get;set;}
public ModelGroup ModelGroup {get;set;}
}
partial class ModelGroup
{
public Model[] Models {get;set;}
}
partial class Model
{
public Name {get;set;}
}
我需要在另一个文件中使用额外的计算属性扩展Calibration类。
partial class Calibration
{
public string ModelGroupName {get;set;}
}
此属性的计算方式如下:
string.Join(" / ", CalibratedDevice.ModelGroup.Models.Select(m => m.Name));
最后,我需要通过此计算属性对校准实体的ObjectSet进行排序。 当然,像
这样的代码Calibrations.OrderBy(c => c.ModelGroupName)
不会抛出异常,因为EF无法将ModelGroupName属性转换为数据库。 当然,我知道最简单的方法:
Calibrations.AsEnumerable().OrderBy(c => c.ModelGroupName)
当然,它对我不起作用,我不想从数据存储中加载所有对象并在linq中对它们进行排序,因为我只需要整个中的一小部分对象集。
我知道存储计算lambda而不是属性并将其传递给OrderBy方法的方法,但它不起作用,因为我有比简单的a + b更复杂的计算逻辑。 例如
partial class Calibration
{
public static Expression<Func<Calibration, string>> ModelGroupName
{
get
{
return c => string.Join(" / ", c.CalibratedDevice.ModelGroup.Models.Select(m => m.Name));
}
}
}
Calibrations.OrderBy(Calibration.ModelGroupName)
将抛出异常,因为EF无法将string.Join方法转换为数据库。 我使用EF的第一个版本,这个烦人的方法转换机制是一场灾难。现在经过EF演化几年后,这个问题就存在了,我可以找到任何合适的解决方案。
所以,请建议使用自定义属性组织IQueryable EF排序的方法,计算逻辑并不直接转换为SQL。 谢谢你的回复。
答案 0 :(得分:1)
您可以将SQL函数映射到Entity Framework中的CLR函数
这是一个如何完成的教程:
http://blogs.microsoft.co.il/blogs/gilf/archive/2009/05/28/entity-sql-user-defined-functions-in-entity-framework-4.aspx
如果您需要进一步的帮助,请与我们联系。
答案 1 :(得分:1)
EF将IQueryable
个对象转换为在db上运行的SQL语句。你问EF是否可以将任意C#代码转换为SQL - 不,它不能。
有可能构造一个返回正确结果集的查询,您的自定义属性可以使用它 - 这取决于逻辑。