LINQ to Entities无法识别Urls.MeaningfulURL方法,并且此方法无法转换为存储表达式

时间:2015-10-12 09:26:49

标签: c# entity-framework linq

此问题特定于获取格式化的网址值并与未格式化的数据库值进行比较。

我有一个网址/ companies / my-company /

公司的名称存储在数据库字段中,作为"我的公司" - 注意:没有连字符,空格和大写。

它可以以更复杂的格式存储,例如"约翰公司>>"因为用户可以在CMS中输入它。

那么如何在LINQ to Entites中将我的公司与My Company进行比较?

var type = Context.Set<Domain.Content.Organisation>()
                        .AsNoTracking()
                        .Select(x => new DataContracts.Content.Organisation
                        {
                            Id = x.Id
                            ,Name = x.Name
                            ,OrganisationTypeId = x.OrganisationTypeId
                            ,OrganisationTypeName = (x.OrganisationType != null) ? x.OrganisationType.Name : string.Empty
                            ,Categories = x.Categories.Select(i => i.Id)
                            ,IsCustomer = x.IsCustomer
                            ,CountryId = x.CountryId
                            ,CountryName = (x.Country != null) ? x.Country.Name : string.Empty,
                            SeoName = x.SeoName,
                            Description = x.Description,                           
                            Website = x.Website
                        })
                        .FirstOrDefault(x => x.Id == id || Urls.MeaningfulURL(x.SeoName.ToLower(), null) == seoName.ToLower());

这里的问题是:

Urls.MeaningfulURL(x.SeoName.ToLower(), null) == seoName.ToLower()

它会产生错误:

LINQ to Entities does not recognize the method Urls.MeaningfulURL method, and this method cannot be translated into a store expression.

我理解这意味着什么,但无法找到解决方法。

Urls.MeaningfulURL是一种执行大量字符串替换的方法,用于创建网址格式&#39; my-company&#39;。

如何正确地在查询时格式化列x.SeoName,以便它匹配我的网址输入?

由于

1 个答案:

答案 0 :(得分:0)

EF无法将Urls.MeaningfulURL转换为SQL。有很多选择可以解决它:

<强> 1。首先加载数据:

var type = Context.Set<Domain.Content.Organisation>()
    .AsNoTracking()
    .Select(your select)
    .ToList()
    .FirstOrDefault(x => x.Id == id || Urls.MeaningfulURL(x.SeoName.ToLower(), null) == seoName.ToLower());

这是最简单的,但它会产生性能问题,导致所有Organisation将从db加载到内存中。

<强> 2。重写你的逻辑。

您无法将自定义方法应用于x.SeoName,所以不要这样做。尝试将您的查询重写为:

var type = Context.Set<Domain.Content.Organisation>()
    .AsNoTracking()
    .Select(your select)
    .FirstOrDefault(x => x.Id == id || computedString.Contains(x.SeoName));

是的,您可以使用Contains,至少对于SQL Server提供商。

第3。将您的逻辑移至SQL:

如果使用SQL Server,您可以尝试计算列,视图甚至CLR code on SQL Server等。

<强> 4。将计算值存储在db:

有时最好存储Urls.MeaningfulURL(x.SeoName.ToLower(), null)值或与x.SeoName一起存储,并在查询中使用此存储值。此外,还可以在此字段上添加索引。