c# - 引用外部类型枚举和包含方法

标签 c# enums mapping entity-framework-5 ef-model-first

自从我切换到 .net 4.5 和 EF 5.0 后,我开始使用枚举映射。 在我的项目中,我首先使用模型。因为所有枚举都是较早声明的,所以我决定在将字段转换为 EDM 中的枚举时使用用户选项“引用外部类型”。一切正常,但是当我尝试执行像

这样的代码时
public enum SomeEnum : int
{
    value1 = 0,
    value2 = 1
}

class Program
{
    static void Main(string[] args)
    {
        TestDbEntities context = new TestDbEntities();
        var enumList = new List<SomeEnum>() { SomeEnum.value1, SomeEnum.value2 };
        var items = context.Table1.Where(e => enumList.Contains(e.EnumField));
        foreach (var item in items)
        {
            Console.Write(item.Id);
        }
        context.Dispose();
    }
}

我收到带有消息的 ArgumentException:

The type 'SomeEnum' does not match the EDM enumeration type 'SomeEnum' or its underlying type 'Int32' Parameter name: value.    

有线的是,当我不使用引用外部类型时,一切都很好。我了解 EDM 背后的内容,但我不明白为什么当枚举在模型中定义并随后由 T4 生成时这段代码有效

  <EntityContainer Name="TestDbEntities" p1:LazyLoadingEnabled="true">
      <EntitySet Name="Table1" EntityType="TestDbModel.Table1" />
    </EntityContainer>
    <EntityType Name="Table1">
      <Key>
        <PropertyRef Name="Id" />
        <PropertyRef Name="EnumField" />
      </Key>
      <Property Name="Id" Type="Int32" Nullable="false" />
      <Property Name="EnumField" Type="TestDbModel.SomeEnum" Nullable="false" />
    </EntityType>
    <EnumType Name="SomeEnum" a:ExternalTypeName="ConsoleApplication1.SomeEnum" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />

我想使用引用外部类型,但这是一些限制。我知道我可以强制转换为基础类型,但这是一个 hack。

----编辑 这是堆栈跟踪

at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateConstant(TypeUsage constantType, Object value)
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__DisplayClass88.<TypedTranslate>b__86(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.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.CreateNewCollection(IEnumerable`1 elements)
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.MethodCallTranslator.ContainsTranslator.TranslateContains(ExpressionConverter parent, Expression sourceExpression, Expression valueExpression)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.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.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 ConsoleApplication1.Program.Main(String[] args) in c:\Users\Pawel\Documents\Visual Studio 2012\Projects\ClassLibrary1\ConsoleApplication1\Program.cs:line 22
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

最佳答案

这是一个错误。我在 EntityFramework Codeplex 网站上提交了它:http://entityframework.codeplex.com/workitem/623 .现在的解决方法是使用 ||或者在 EDM 枚举类型中指定您在 CLR 枚举类型中拥有的所有成员。 设置外部枚举类型会向 EDM 枚举类型添加注释 (a:ExternalTypeName="ConsoleApplication1.SomeEnum"),告诉代码生成器不要生成此类型,而是在生成的代码中使用该类型的任何地方使用该属性的值。如果没有此注释,将生成与 EDM 枚举类型完全匹配的 CLR 枚举。顺便提一句。前段时间我写了一篇关于 EF5 和外部枚举类型的博文。您可以在这里找到它:http://blog.3d-logic.com/2012/09/11/using-exisiting-enum-types-in-entity-framework-5/ .我将在博客上添加有关该错误的信息。也请随时对此发表评论。

关于c# - 引用外部类型枚举和包含方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13049202/

相关文章:

java - 在 Hibernate 中映射两个表 0..n

c# - Microsoft.Build.Engine 错误(默认目标): Target GetFrameworkPaths: Could not locate the . NET Framework SDK

c# - 数据流 TransformManyBlock throttle

enums - 如何使用 Dart/Flutter 将枚举属性序列化/反序列化到 Firestore?

javascript - 在javascript中使用枚举实现对象的正确方法

vim - 为什么我的 vim 映射不起作用?

javascript - 如何将数组中的对象转换为特定格式

c# - 使用 C# MySQL 连接器进行批量更新的最快、最有效的方法是什么?

c# - 在一台服务主机中托管多个服务?

java - Hibernate 中的枚举,作为枚举持久存在