gpt4 book ai didi

entity-framework-4 - 无法使用 LINQ to Entities 和 LinqKit/PredicateBuilder 进行重构

转载 作者:行者123 更新时间:2023-12-04 14:48:28 24 4
gpt4 key购买 nike

我一直在尝试将 LINQ 表达式重构为一个方法,并且遇到了“Internal .NET Framework Data Provider error 1025.”和“The parameter 'xyz' was not bound in the specified LINQ to Entities query expression.”异常。

以下是实体模型的相关部分(使用 EF 4.2/LINQ to Entities):

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实体 OfficialNameterm 开头或者谁有 PlaceName谁的 TextAsciiEquivalent从搜索开始 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()的几种组合在谓词上,但总是以上述异常(exception)之一结束。

甚至可以使用带有 LinqKit/PredicateBuilder 的 LINQ to Entities 将此表达式分解为单独的方法吗? 如果是这样,如何?我究竟做错了什么?

最佳答案

下面的方法应该有效:

private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
Expression<Func<PlaceName, bool>> placeNameExpr = PlaceNameMatches(term);
Expression<Func<Place, bool>> placeExpr =
place => place.Names.Any(name => placeNameExpr.Invoke(name));
return placeExpr.Expand();
}

编辑:添加额外的解释
PlaceNameMatches方法按您编写的方式工作。您的问题在于您如何使用该方法。如果您想分解出表达式的一部分,请按照我在上述方法中执行的 3 个步骤进行操作。
  • 将局部变量设置为由方法创建的表达式。
  • 将另一个局部变量设置为调用局部变量表达式的新表达式。
  • 调用 LinkKit Expand方法:这将扩展任何调用的表达式
  • 关于entity-framework-4 - 无法使用 LINQ to Entities 和 LinqKit/PredicateBuilder 进行重构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10689506/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com