首页 新闻 会员 周边

Entity Framework 上有没有办法实现自定义函数查询?

0
悬赏园豆:15 [已解决问题] 解决于 2015-07-02 18:49

我要实现对某一字段的查询,查询关键字是两个或两个以上的字符串,但查出来的相邻两个关键字的间距必须在20个字符以内,这样可以保持它们关系比较密切。

下面的代码在EF中无法成功,错误是:

NotSupportedException
方法“Boolean IsNearKeys(System.String, System.Collections.Generic.List`1[System.String])”不支持转换为 SQL。
Message 方法“Boolean IsNearKeys(System.String, System.Collections.Generic.List`1[System.String])”不支持转换为 SQL。
Data
(0 items)
InnerException null
TargetSite
6RuntimeMethodInfo4
Visitor.VisitMethodCall (SqlMethodCall mc)
Name VisitMethodCall
DeclaringType
ReflectedType
CustomAttributes
(0 items)
MetadataToken 100667032
Module
MethodImplementationFlags IL
MethodHandle
6RuntimeMethodHandle4
System.RuntimeMethodHandle
Value
IntPtr
1392319092
Attributes PrivateScope, Assembly, Virtual, HideBySig, CheckAccessOnOverride
CallingConvention Standard, HasThis
IsGenericMethodDefinition False
ContainsGenericParameters False
IsGenericMethod False
IsSecurityCritical False
IsSecuritySafeCritical False
IsSecurityTransparent True
IsPublic False
IsPrivate False
IsFamily False
IsAssembly True
IsFamilyAndAssembly False
IsFamilyOrAssembly False
IsStatic False
IsFinal False
IsVirtual True
IsHideBySig True
IsAbstract False
IsSpecialName False
IsConstructor False
MemberType Method
ReturnType
ReturnParameter
6RuntimeParameterInfo4
System.Data.Linq.SqlClient.SqlExpression
ParameterType
Name null
HasDefaultValue True
DefaultValue null
RawDefaultValue null
Position -1
Attributes None
Member
qRuntimeMethodInfo4
Visitor.VisitMethodCall (SqlMethodCall mc)
IsIn False
IsOut False
IsLcid False
IsRetval False
IsOptional False
MetadataToken 134217728
CustomAttributes
(0 items)
ReturnTypeCustomAttributes
6RuntimeParameterInfo4
System.Data.Linq.SqlClient.SqlExpression
ParameterType
Name null
HasDefaultValue True
DefaultValue null
RawDefaultValue null
Position -1
Attributes None
Member
qRuntimeMethodInfo4
Visitor.VisitMethodCall (SqlMethodCall mc)
IsIn False
IsOut False
IsLcid False
IsRetval False
IsOptional False
MetadataToken 134217728
CustomAttributes
(0 items)
StackTrace    在 System.Data.Linq.SqlClient.PostBindDotNetConverter.Visitor.VisitMethodCall(SqlMethodCall mc)    在 System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)    在 System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp)    在 System.Data.Linq.SqlClient.SqlVisitor.VisitSelectCore(SqlSelect select)    在 System.Data.Linq.SqlClient.PostBindDotNetConverter.Visitor.VisitSelect(SqlSelect select)    在 System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)    在 System.Data.Linq.SqlClient.SqlVisitor.VisitAlias(SqlAlias a)    在 System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)    在 System.Data.Linq.SqlClient.SqlVisitor.VisitSource(SqlSource source)    在 System.Data.Linq.SqlClient.SqlVisitor.VisitSelectCore(SqlSelect select)    在 System.Data.Linq.SqlClient.PostBindDotNetConverter.Visitor.VisitSelect(SqlSelect select)    在 System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)    在 System.Data.Linq.SqlClient.PostBindDotNetConverter.Convert(SqlNode node, SqlFactory sql, ProviderMode providerMode)    在 System.Data.Linq.SqlClient.SqlProvider.BuildQuery(ResultShape resultShape, Type resultType, SqlNode node, ReadOnlyCollection`1 parentParameters, SqlNodeAnnotations annotations)    在 System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations)    在 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)    在 System.Data.Linq.DataQuery`1.System.Collections.IEnumerable.GetEnumerator()    在 LINQPad.ObjectGraph.ListNode.<GetItems>d__8.MoveNext()    在 System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)    在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)    在 LINQPad.ObjectGraph.ListNode..ctor(ObjectNode parent, IEnumerable list, GraphOptions options, String name)    在 LINQPad.ObjectGraph.ObjectNode.CreateInternal(ObjectNode parent, Object item, GraphOptions options)
HelpLink null
Source System.Data.Linq
HResult -2146233067

 

void Main()
{
    var keys = new List<string>();
    keys.Add("女子");
    keys.Add("须发");
    
    var query = from item in CM_BookPageDetails
            where IsNearKeys(item.Content,keys)
            select item;
    query.Take(10).Dump();
}

bool IsNearKeys(string source, List<string> keys)
{
    var lastCharIndex = 0;
    for(var i=0;i<keys.Count ;i++)
    {
        var charIndex = source.IndexOf(keys[i]);
        if(i>0 && charIndex - lastCharIndex > 20)
            return false;
            
        lastCharIndex = charIndex;
    }
    return true;
}

// Define other methods and classes here
问题补充:

有没有办法继承某些接口让它支持我的自定义方法?

空明流光的主页 空明流光 | 初学一级 | 园豆:106
提问于:2015-07-02 18:10
< >
分享
最佳答案
0

原来我自己是可以解决的,方案如下:

void Main()
{
    var keys = new List<string>();
    keys.Add("女子");
    keys.Add("须发");
//    keys.Add("如男子");
    
    var filters  = new List<System.Linq.Expressions.Expression<Func<LINQPad.User.CM_BookPageDetail, bool>>>();
    foreach(var key in keys)
        filters.Add(item=>item.Content.Contains(key));
    for(var i=0;i<keys.Count ;i++)
    {
        if(i>0)
        {
            var lastKey = keys[i-1];
            var currentKey = keys[i];
            filters.Add(item=> item.Content.IndexOf(currentKey) - item.Content.IndexOf(lastKey) < 20);
        }
    }
    
    var query = from item in CM_BookPageDetails
            select item;
    
    foreach(var filter in filters)
        query = query.Where(filter);
    
    query.Take(10).Dump();
}

// Define other methods and classes here
空明流光 | 初学一级 |园豆:106 | 2015-07-02 18:49
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册