我在使用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()
{
}
}
答案 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语句。我总是想知道为什么实体框架本身不会执行这种重写,只是用主键的比较替换实体的所有比较,但可能有我不知道的边缘情况。