2013-11-25 59 views
0

如何在使用实体框架查询数据实体时运行函数?如何在使用实体框架查询数据实体时运行函数?

var name = "First name"; 
// it throws exception here 
var result = contactRepository.Query.FirstOrDefault(x => SanitizeUserInput(x.Name) == name); 

public static string SanitizeUserInput(string value) 
{ 
    if (string.IsNullOrEmpty(value)) 
     return string.Empty; 

    var htmlDecodedValue = HttpUtility.HtmlDecode(value); 
    return Regex.Replace(htmlDecodedValue ?? string.Empty, "<.*?>", string.Empty); 
} 

查询是IQueryable类型的。

我得到下面的错误:

LINQ to Entities does not recognize the method 'System.String SanitizeUserInput(System.String)' method, and this method cannot be translated into a store expression.

回答

1

实体框架的工作方式如下 - 将其转换表达式树到SQL文本查询,然后使用旧的好ADO.NET执行查询。自定义函数不能被实体框架提供者翻译成SQL。您只能在内存中运行自定义函数:

var result = contactRepository.Query.AsEnumerable() 
       .FirstOrDefault(c => SanitizeUserInput(c.Name) == name); 

这将生成SQL查询以从数据库获取所有数据并执行它。然后,您将枚举逐个读取DataReader行的结果,将数据映射到实体并执行SanitizeUserInput方法,直到满足条件。

+0

所以基本上你的意思是我不得不借出内存中的所有数据,然后应用过滤器。这会严重影响性能。我在想也许增加一个SQL函数或存储过程可能会表现更好? –

+0

@TheLight并不总是所有的数据都会被加载到内存中,正如我上面所描述的那样,只有当没有符合FirstOrDefault条件的数据时,才会将所有数据加载到内存中。否则,当找到匹配时,您将停止获取数据。但是,是的,与运行纯SQL查询相比,这是一个很好的性能 –

+0

@TheLight是的,存储过程或SQL函数将允许您在服务器端执行所有的操作,但这是EF无法帮助您的部分 - 您应该翻译您的自定义方法手动转换为SQL –