2011-09-28 73 views
3

我目前遇到了一些使用EF代碼的linq問題。我當前的代碼工作正常:EF-Code First:無法創建類型爲''的常量值。在這種情況下,只支持原始類型(如Int32,String和Guid)

我的數據庫模型

public class MyDatabase : DbContext 
{ 
    public DbSet<Person> People { get; set; } 
    public DbSet<Role> Roles { get; set; } 
    public DbSet<Visit> Visits { get; set; } 
} 

public class Person 
{ 
    public int PersonId { get; set; } 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
} 

public class Visit 
{ 
    public int VisitId { get; set; } 
    public string Name {get; set;} 
    public int PersonId { get; set; } 
    public string VisitStatus { get; set; } 
    public virtual Person People { get; set; } 
    //There is a one to many relationship to person 
} 

public class Role 
{ 
    public Role() 
    { 
     People = new HashSet<Person>(); 
    } 

    [Key] 
    public int RoleId { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Person> People { get; set; } 
    //There is a many to many relationship to person 
} 

我查詢

public IEnumerable<VisitDetails> GetGuestVisiterList() 
{ 
    using (var db = new MyDatabase()) 
    { 
     return (from p in db.People 
     where p.Roles.Any(a => a.Name == "Guest") 
     select new GuestVisitDetails 
      { 
       PersonId = p.PersonId, 
       Forename = p.Forename, 
       Surname = p.Surname, 
       NumberOfVisits = db.Visits.Count(v => v.PersonId == p.PersonId && v.VisitStatus != "Complete") 
      }).ToList(); 

    }  
} 

我的視圖模型

public class GuestVisitDetails 
{ 
    public int PersonId { get; set; } 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
    public int NumberOfVisits { get; set; } 
} 

但是當我嘗試使用一個接口,用於我的數據庫模型,所以我可以單元測試,它會得到以下錯誤:

Unable to create a constant value of type 'MyVisits.Data.Model.Visit'. Only primitive types ('such as Int32, String, and Guid') are supported in this context 

我的數據庫建設界面

public class MyDatabase : DbContext, IDolphinDatabase 
{ 
    public IDbSet<Person> People { get; set; } 
    public IDbSet<Role> Roles { get; set; } 
    public IDbSet<Visit> Visits { get; set; } 
} 

public interface IMyDatabase : IDisposable 
{ 
    public IDbSet<Person> People { get; set; } 
    public IDbSet<Role> Roles { get; set; } 
    public IDbSet<Visit> Visits { get; set; } 
} 

我的新的查詢,我創建了一個dbFactory只得到了IMyDatabase

public IEnumerable<VisitDetails> GetGuestVisiterList(int paperId) 
{ 
    using (var db = _dbFactory.GetDatabase()) 
    { 
     return (from p in db.People 
       where p.Roles.Any(a => a.Name == "Guest") 
       select new GuestVisitDetails 
       { 
        PersonId = p.PersonId, 
        Forename = p.Forename, 
        Surname = p.Surname, 
        NumberOfVisits = db.Visits.Count(v => v.PersonId == p.PersonId && v.VisitStatus != "Complete") 
       }).ToList(); 
    }  
} 

我發現它是 'NumberOfVisits' 這是造成這個問題,但我不確定爲什麼或如何解決它。

按照要求堆棧跟蹤

[NotSupportedException: Unable to create a constant value of type 'MyVisits.Data.Model.Visit'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.] 
System.Data.Objects.ELinq.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq) +902 
System.Data.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +54 
System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +110 
System.Data.Objects.ELinq.<>c__DisplayClass77.<TypedTranslate>b__75(Expression e) +11 
System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151 
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) +237 
System.Data.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator`3.Validate() +46 
System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.CreateExpressionList(IEnumerable`1 arguments, String argumentName, Boolean allowEmpty, Action`2 validationCallback) +142 
System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateNewCollection(IEnumerable`1 elements, DbExpressionList& validElements) +72 
System.Data.Objects.ELinq.NewArrayInitTranslator.TypedTranslate(ExpressionConverter parent, NewArrayExpression linq) +121 
System.Data.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +54 
System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +110 
System.Data.Objects.ELinq.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq) +520 
System.Data.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +54 
System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +110 
System.Data.Objects.ELinq.AggregateTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) +86 
System.Data.Objects.ELinq.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) +14 
System.Data.Objects.ELinq.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) +102 
System.Data.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +54 
System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +110 
System.Data.Objects.ELinq.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq) +310 
System.Data.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +54 
System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +110 
System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input) +80 
System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding) +88 
System.Data.Objects.ELinq.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda) +85 
System.Data.Objects.ELinq.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) +37 
System.Data.Objects.ELinq.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) +14 
System.Data.Objects.ELinq.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) +102 
System.Data.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +54 
System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +110 
System.Data.Objects.ELinq.ExpressionConverter.Convert() +16 
System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) +110 
System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +149 
System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +44 
System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator() +40 
System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator() +40 
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +315 
System.Linq.Enumerable.ToList(IEnumerable`1 source) +58 
MyVisits.Business.<GetGuestVisiterList>c__Binding.Invoke(Object& instance, Arguments arguments, Object aspectArgs) in E:\Visual Studio\Projects\MyVisits_current\MyVisits.Business\VisitService.cs:459 
PostSharp.Aspects.Internals.MethodInterceptionArgsImpl`1.Proceed() +23 
MvcMiniProfiler.Aop.MiniProfilerAttribute.OnInvoke(MethodInterceptionArgs args) in E:\Visual Studio\Projects\MyVisits_current\MvcMiniProfiler.Aop\MiniProfilerAttribute.cs:17 
MyVisits.Business.VisitService.GetGuestVisiterList() in :0 
MyVisits.Web.Areas.RegionalAdministrator.Controllers.VisitController.EditVisitor() in E:\Visual Studio\Projects\MyVisits_current\MyVisits.Web\Areas\RegionalAdministrator\Controllers\VisitController.cs:85 
lambda_method(Closure , ControllerBase , Object[]) +101 
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17 
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208 
Castle.Proxies.ControllerActionInvokerProxy.InvokeActionMethod_callback(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27 
Castle.Proxies.Invocations.ControllerActionInvoker_InvokeActionMethod.InvokeMethodOnTarget() +154 
Castle.DynamicProxy.AbstractInvocation.Proceed() +56 
Glimpse.Mvc3.Interceptor.InvokeActionMethodInterceptor.Intercept(IInvocation invocation) +336 
Castle.DynamicProxy.AbstractInvocation.Proceed() +94 
Castle.Proxies.ControllerActionInvokerProxy.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +214 
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263 
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263 
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191 
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343 
System.Web.Mvc.Controller.ExecuteCore() +116 
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97 
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10 
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37 
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21 
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12 
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50 
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7 
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22 
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60 
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8920029 
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184 

任何幫助將是巨大的

+0

「GuestVisitDetails」的定義在哪裏? – Kori

+0

對不起,現在添加到問題 –

+0

整個堆棧的異常可能會有所幫助(要知道linq表達式解析涉及) –

回答

2

首先,你要改變你的實體,來支持你的人際關係:

public class Person 
{ 
    public int PersonId { get; set; } 
    public string Forename { get; set; } 
    public string Surname { get; set; } 

    // add a collection-reference to roles 
    public virtual ICollection<Role> Roles { get; set; } 

    // add a collection-reference to visites 
    public virtual ICollection<Visit> Visits { get; set; } 
} 

public class Visit 
{ 
    public int VisitId { get; set; } 
    public string Name {get; set;} 
    public string VisitStatus { get; set; } 

    public int PersonId { get; set; } 
    public virtual Person People { get; set; } 
    //There is a one to many relationship to person 
} 

public class Role 
{ 
    public Role() 
    { 
     People = new HashSet<Person>(); 
    } 

    [Key] 
    public int RoleId { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Person> People { get; set; } 
    //There is a many to many relationship to person 
} 

您的問題現在已解決。但你也可以這樣改變查詢:

public IEnumerable<VisitDetails> GetGuestVisiterList(int paperId) 
{ 
    using (var db = _dbFactory.GetDatabase()) 
    { 
     return (from p in db.People 
       where p.Roles.Any(a => a.Name == "Guest") 
       select new GuestVisitDetails 
       { 
        PersonId = p.PersonId, 
        Forename = p.Forename, 
        Surname = p.Surname, 
        NumberOfVisits = p.Visits.Count(v => v.VisitStatus != "Complete") 
       }).ToList(); 
    }  
} 

讓我知道你是否有任何問題或需要澄清的任何部分。乾杯。

+0

謝謝,這就解決了我的問題。乾杯 –

+0

歡迎您:D –

相關問題