LINQ to Entities无法识别布尔值IsAssignableFrom方法

时间:2013-06-30 22:49:12

标签: c# asp.net-mvc linq entity-framework

我有一个扩展方法IsAssignableFrom

public static bool IsTypeOf<T>(this Type type)
        {
            return typeof (T).IsAssignableFrom(type);
        }

由以下人员召集:

var Type = typeof(BadgeNumVotesOnItem);    
var UnlockableBadges = DB.Badges.Where(t => t.GetType().IsAssignableFrom(Type));

然而,当我使用它时,它会抛出这个异常:

{System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean IsAssignableFrom(System.Type)' method, and this method cannot be translated into a store expression.
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.Convert()
   at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
   at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
   at MVCDaemon.Helpers.AwardBadgesProcessor.AwardBadgesForEventViewedSituation() in c:\Users\William-Business\Desktop\TWB\Entrepreneurial dev\Hehe\Hehe.Daemon\Processors\hehehe.cs:line 27
   at MVCDaemon.Controllers.AwardBadgesController.FromUnprocessedEvents() in c:\Users\William-Business\Desktop\TWB\Entrepreneurial dev\Hehe\Hehe.Daemon\Controllers\hehehe.cs:line 29}

2 个答案:

答案 0 :(得分:3)

您正在寻找的是:

var UnlockableBadges = DB.Badges.OfType<BadgeNumVotesOnItem>();

假设1)BadgeNumVotesOnItem是徽章的子类,两者都在您的实体框架映射中定义(或者在数据库中以TPT / TPH方式定义)。

否则,这是不可能的,因为SQL不知道未映射到表的.Net类。

* 编辑:您不能仅因为它继承您的模型而使用它。因为您正在混合与数据库中的某些内容具有有意义关系的对象(EF理解并可用于与数据库通信的内容)以及仅存在于应用程序中的内容。你不能混搭。在使用EF实现LINQ查询之前,必须在您在上下文中定义的模型的思维模式中完成所有操作。

让我们来看看你的问题:

DB.Badges.Where(t => t.GetType().IsAssignableFrom(Type));

DB.Badges表示持久层中的表,实体框架知道如何与它进行对话。实体框架将分析Where构造,以转换为持久层可以理解的内容。 Badges集将能够实现(即:将记录转换为有意义的类)类Badge就好了,但数据库不会与BadgeNumVotesOnItem进行对话,因此,实体框架用它做不了多少。

以这种方式思考:如果您直接连接到数据库,是否可以查询BadgeNumVotesOnItem

答案 1 :(得分:1)

你可以试试这个:

var Type = typeof(BadgeNumVotesOnItem); 
var UnlockableBadges = DB.Badges.OfType<BadgeNumVotesOnItem>();

如果您的上下文没有定义类或任何内容,那么您可以这样做:

var Type = typeof(BadgeNumVotesOnItem);    
var UnlockableBadges = DB.Badges.AsEnumerable().Where(t => t.GetType().IsAssignableFrom(Type));
然后,

将构造一个将返回所有标记的SQL查询,然后应用Where表达式。而不是试图将表达式转换为SQL查询,而不是由您正在使用的任何SQL引擎完成。