Linq To Entities [无法创建类型'...'的常量值]

时间:2013-11-21 22:47:00

标签: linq entities

我在使用linq查询时遇到了困难。见下文。

var userHelper = new UserHelper(dbContext);

var currentUser = (from u in dbContext.Users
                     where u.UserID == request.VTIUser.UserID
                     select u).SingleOrDefault();

var userIds = (from u in dbContext.Users
               from r in dbContext.OrgRanges
               select u.UserID).ToList();

只有一个来自子句,它可以正常工作。

异常消息

无法创建“VTI.Entities.OrgRange”类型的常量值。在此上下文中仅支持原始类型(例如Int32,String和Guid')。

堆栈跟踪

at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression 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.NewArrayInitTranslator.<>c__DisplayClass77.<TypedTranslate>b__75(Expression e)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()   
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator`3.Validate(IEnumerable`1 argument, String argumentName, Int32 expectedElementCount, Boolean allowEmpty, Func`3 map, Func`2 collect, Func`3 deriveName)   
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator`3.Validate()  
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.CreateExpressionList(IEnumerable`1 arguments, String argumentName, Boolean allowEmpty, Action`2 validationCallback)
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateNewCollection(IEnumerable`1 elements, DbExpressionList& validElements)
at System.Data.Objects.ELinq.ExpressionConverter.NewArrayInitTranslator.TypedTranslate(ExpressionConverter parent, NewArrayExpression 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.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression 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.SelectManyTranslator.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 System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at CrewSheetWebService.Controllers.UsersController.GetUsers() in c:\Users\patrich.ISCDEVELOPMENT\Documents\Visual Studio 2010\WebSites\St Paul\App_Code\WebAPI\Controllers\UsersController.cs:line 53
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)  

用户模型

  [Table("tblUsers")]
  public class User
  {
    [Key]
    public int UserID { get; set; }

    [StringLength(10)]
    public string EmpNumber { get; set; }

    [StringLength(10)]
    public string Appointment { get; set; }

    [StringLength(6)]
    public string OrgLevel1 { get; set; }

    [StringLength(6)]
    public string OrgLevel2 { get; set; }

    [StringLength(6)]
    public string OrgLevel3 { get; set; }

    [StringLength(200)]
    public string EmpName { get; set; }

    [StringLength(200)]
    public string Email { get; set; }

    [StringLength(15)]
    public string Phone { get; set; }

    public DateTime HireDate { get; set; }

    [StringLength(50)]
    public string Password { get; set; }

    public int? Supervisor { get; set; }

    public int? Role { get; set; }

    public int? PayCycleID { get; set; }

    public int DocumentGroupID { get; set; }

    public DateTime EffectedDate { get; set; }

    public DateTime ExpirationDate { get; set; }

    public int? GroupID { get; set; }

    public int? EmpPosition { get; set; }

    public int? EmpStatus { get; set; }

    public int PunchID { get; set; }

    [ForeignKey("PunchID")]
    public virtual PunchProfile PunchProfile { get; set; }

    [StringLength(50)]
    public string ADUserID { get; set; }

    [StringLength(10)]
    public string Pin { get; set; }

    [StringLength(10)]
    public string Union1 { get; set; }

    [StringLength(10)]
    public string Union2 { get; set; }

    [StringLength(10)]
    public string Union3 { get; set; }

    public decimal? HourlyRate { get; set; }

    public int? PayType { get; set; }

    public int? FLSAProfile { get; set; }

    public int? FMLVProfile { get; set; }

    public int? PercentFullTime { get; set; }

    public DateTime? LastModified { get; set; }

    public virtual ICollection<UserJob> UserJobs { get; set; }

    public virtual ICollection<UserSkill> UserSkills { get; set; }

    public virtual ICollection<UserSchedule> UserSchedules { get; set; }

    public virtual ICollection<UserRange> Ranges { get; set; }

    public static UserSchedule GetCurrentUserSchedule(IList<UserSchedule> userScheds)
    {
      return userScheds.Where(us => DateTime.Now.IsBetween(us.StartDate, us.EndDate)).FirstOrDefault();
    }

    public User()
    {
    }

    public bool HasRole(int role)
    {
      return (Role & role) == role;
    }
  }

OrgRange模型

  [Table("tblOrgRanges")]
  public class OrgRange
  {
    [Key]
    public int RangeID { get; set; }

    public int GroupID { get; set; }

    [ForeignKey("GroupID")]
    public virtual Group Group { get; set; }

    [StringLength(30)]
    public string RangeName { get; set; }

    [StringLength(100)]
    public string RangeDescription { get; set; }

    [StringLength(6)]
    public string OrgLevel1Min { get; set; }

    [StringLength(6)]
    public string OrgLevel1Max { get; set; }

    [StringLength(6)]
    public string OrgLevel2Min { get; set; }

    [StringLength(6)]
    public string OrgLevel2Max { get; set; }

    [StringLength(6)]
    public string OrgLevel3Min { get; set; }

    [StringLength(6)]
    public string OrgLevel3Max { get; set; }

    public DateTime EffectiveDate { get; set; }

    public DateTime ExpirationDate { get; set; }

    // Don't use this function in a LINQ Where clause. It won't work.
    public bool Include(string orgLevel1, string orgLevel2, string orgLevel3)
    {
      return (OrgLevel1Min.CompareTo(orgLevel1) <= 0 && OrgLevel1Max.CompareTo(orgLevel1) >= 0)
        && (OrgLevel2Min.CompareTo(orgLevel2) <= 0 && OrgLevel2Max.CompareTo(orgLevel2) >= 0)
        && (OrgLevel3Min.CompareTo(orgLevel3) <= 0 && OrgLevel3Max.CompareTo(orgLevel3) >= 0);
    }

    public OrgRange()
    {
    }
  }

1 个答案:

答案 0 :(得分:1)

问题是实体框架不知道如何将实体转换为SQL。我无法在您提供的代码中发现此问题,但我想您将能够使用以下示例找到有问题的代码。

var user = GetUserById(42);

var orders = context.Orders.Where(order => order.Customer == customer);

这将失败,因为实体框架不知道如何将两个用户实体的比较转换为SQL。要解决此问题,您必须使用主键比较重写此内容。

var user = GetUserById(42);

var orders = context.Orders.Where(order => order.Customer.Id == customer.Id);

这将起作用,因为实体框架现在可以看到ID,整数的比较,并且能够将其转换为SQL语句。我总是想知道为什么实体框架本身不会执行这种重写,只是用主键的比较替换实体的所有比较,但可能有我不知道的边缘情况。