按实体框架中的自定义实体属性排序

时间:2011-11-01 14:00:16

标签: c# entity-framework

关于实体框架实体中自定义扩展属性的另一个问题。

实体模型一般来说非常简单。当然实际上它更复杂,但仅仅是因为我没有粘贴所有生成的代码,只是类和所需的属性。 所以,我有实体类:

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。 谢谢你的回复。

2 个答案:

答案 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 - 不,它不能。

有可能构造一个返回正确结果集的查询,您的自定义属性可以使用它 - 这取决于逻辑。