我一直在嘗試將LINQ表達式重構爲一個方法,並且已經遇到了「Internal .NET Framework Data Provider error 1025.
」和「The parameter 'xyz' was not bound in the specified LINQ to Entities query expression.
」異常。無法重構使用LINQ to Entities和LinqKit/PredicateBuilder
下面是實體模型的相關部分(使用EF 4.2/LINQ到實體):
public class Place : Entity
{
public string OfficialName { get; protected internal set; }
public virtual ICollection<PlaceName> { get; protected internal set; }
}
public class PlaceName : Entity
{
public string Text { get; protected internal set; }
public string AsciiEquivalent { get; protected internal set; }
public virtual Language TranslationTo { get; protected internal set; }
}
public class Language : Entity
{
public string TwoLetterIsoCode { get; protected internal set; }
}
基本關係模型是這樣的:
Place (1) <-----> (0..*) PlaceName (0..*) <-----> (0..1) Language
我想創建一個當給定搜索term
時,將嘗試查找Place
實體,其OfficialName
以term
開頭或者具有PlaceName
的實體,其Text
或AsciiEquivalent
從搜索term
開始。 (Language
是不是在那裏我遇到了問題,但它是查詢的一部分,因爲PlaceName
S的關係只匹配了CultureInfo.CurrentUICulture.TwoLetterIsoLanguageName
)
下面的代碼確實工作:
internal static IQueryable<Place> WithName(this IQueryable<Place> queryable,
string term)
{
var matchesName = OfficialNameMatches(term)
.Or(NonOfficialNameMatches(term));
return queryable.AsExpandable().Where(matchesName);
}
private static Expression<Func<Place, bool>> OfficialNameMatches(string term)
{
return place => place.OfficialName.StartsWith(term);
}
private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
return place => place.Names.Any(
name =>
name.TranslationToLanguage != null
&&
name.TranslationToLanguage.TwoLetterIsoCode == currentLanguage
&&
(
name.Text.StartsWith(term)
||
(
name.AsciiEquivalent != null
&&
name.AsciiEquivalent.StartsWith(term)
)
)
);
}
接下來我要做的是重構NonOfficialNameMatches
方法,將name => ...
表達式提取到一個單獨的方法中,以便它可以被其他查詢重用。下面是一個例子,我已經盡力了,這不起作用並拋出異常「The parameter 'place' was not bound in the specified LINQ to Entities query expression.
‘:
private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
return place => place.Names.AsQueryable().AsExpandable()
.Any(PlaceNameMatches(term));
}
public static Expression<Func<PlaceName, bool>> PlaceNameMatches(string term)
{
var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
return name =>
name.TranslationToLanguage != null
&&
name.TranslationToLanguage.TwoLetterIsoCode == currentLanguage
&&
(
name.Text.StartsWith(term)
||
(
name.AsciiEquivalent != null
&&
name.AsciiEquivalent.StartsWith(term)
)
);
}
當我沒有.AsExpandable()
鏈NonOfficialNameMatches
,然後我得到了’Internal .NET Framework Data Provider error 1025.
」異常。
我跟着other advice here,例如在謂詞上調用.Expand()
的幾種組合,但總是以上述例外之一結束。
甚至有可能將這個表達式分解成一個單獨的方法,使用LINQ to Entities和LinqKit/PredicateBuilder?如果是這樣,怎麼樣?我究竟做錯了什麼?
+100,謝謝我開始覺得這個問題永遠不會得到回答。額外的解釋也有幫助。 – danludwig