2013-11-21 3 views
1

나는 linq 쿼리에 어려움을 겪고 있습니다. 아래를 참조하십시오. 하나의 절에서와엔티티에 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

'User'와'OrgRange' 모델 클래스를 게시 할 수 있습니까? –

답변

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 문에이 변환 할 수 있기 때문에이 작동합니다. Entity Framework가이 재 작성을 자체적으로 수행하지 않는 이유는 언제나 궁금합니다. 엔터티의 모든 비교를 기본 키의 비교로 바꾸면됩니다. 그러나 잘 모르는 경우가 있습니다.

+1

Daniel Bruckner : 감사합니다. 당신이주는 모범을 이해합니다. 내 코드는 엔티티 비교를 수행하지 않습니다. from 문은 개별적으로 잘 작동합니다. 이 오류는 차례로 체인을 연결할 때 발생합니다. –

+0

간단한 예제로 시도해 보았습니다. 당신과 같은 쿼리가 저에게 잘 작동합니다. 나는 당신이 당신의 질문에서 언급 한 질의가 문제의 실제 원인이라고 확신하지 못한다. 실제 원인은 쿼리의 부작용 일 수 있습니다. UsersController.cs 줄 53 주위에 더 많은 코드를 제공 할 수 있습니까? 검색하는 유일한 항목이 엔티티 중 하나의 ID 일 때 왜 처음에 교차 조인을 수행합니까? –

+0

문제 코드 바로 앞에 두 줄의 코드를 추가했습니다. 이것이 바로 기능의 시작입니다. currentUser에 값을 할당하는 행은 오류가 아닙니다. –