If you are using the Entity Framework and upgrade to .net 4.5 you may run into this problem. This one took me a while to figure out so I thought I would share what I found.
So I got a stack trace with the following message:
System.Data.MetadataException
Schema specified is not valid. Errors: The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'MultisiteSetting'. Previously found CLR type '...', newly found CLR type '...'.
This error made no sense because it the executing code had nothing to do with the types specified in the error message. After looking at this
link , I saw that they added enum support in this version of the .net framework for the entity framework. So I looked at the linq query that was failing and noticed that I was sending enums into the where condition of the query. We almost never do this
so the code caught my attention. Here is an example:
public enum PersonType
{
Good = 0,
Bad = 1
}
PersonType personType = PersonType.Bad;
//PersonType column is an integer
var query = from q in context.Persons
where (PersonType)q.PersonType == personType
select q;
query.ToList();
This will cause the exception provided above. Instead you can do this:
public enum PersonType
{
Good = 0,
Bad = 1
}
PersonType personType = PersonType.Bad;
//PersonType column is an integer
var query = from q in context.Persons
where q.PersonType == (int)personType
select q;
query.ToList();
This will cause the exception provided above. Instead you can do this:
public enum PersonType
{
Good = 0,
Bad = 1
}
PersonType personType = PersonType.Bad;
//PersonType column is an integer
var query = from q in context.Persons
where q.PersonType == (int)personType
select q;
query.ToList();
Many thanks for sharing such a nice solution for us! Welcome to our fourm next time.
Do you mind providing more details for this? Are you using CodeFirst? If so what version are you using? Can you provide the full stack trace and the full error message with type names? Do you by any chance have mulitple MultisiteSetting types (like entity
and enum type) in different namespaces (and possibly in different assemblies). Can you show how the MulisiteSetting entity type looks like and how the entity used for context.Persons?
I can get the whole stack for you. I am not using code first. Just the POCO entities in EF 4.1. There are a couple classes with that name in different assemblies with this name, no enums just classes, however it appears to have nothing to do with the
error. All you should need for the repro is what I provided. I may be able to send you a solution with a repro if you need it after getting this information. I actually have discovered another issue with annonomous types. Oh boy, it is a bad one. I will
try to get some information up here about it when I have more information.
By the way, the context.Persons what just a bogus example. Here is the full stack:
System.Data.MetadataException: Schema specified is not valid. Errors:
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type '...'. Previously found CLR type '...', newly found CLR type '...'.
at System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, Boolean loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action`1 logLoadMessage)
at System.Data.Metadata.Edm.ObjectItemCollection.ImplicitLoadAssemblyForType(Type type, EdmItemCollection edmItemCollection)
at System.Data.Metadata.Edm.MetadataWorkspace.ImplicitLoadAssemblyForType(Type type, Assembly callingAssembly)
at System.Data.Objects.ELinq.ExpressionConverter.TryGetValueLayerType(Type linqType, TypeUsage& type)
at System.Data.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime)
at System.Data.Objects.ELinq.ExpressionConverter.ConvertTranslator.TranslateUnary(ExpressionConverter parent, UnaryExpression unary, DbExpression operand)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BitwiseBinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.NotTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression 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.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.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
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.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression 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.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
It looks to me that the enum type lives in a separate assembly and the cast triggers loading types from this assembly. This assembly happen to contain the type 'DTO.A' which matches the 'Entities.A' type. This cause the ambiguity which in turn causes
an exception to be thrown. Note that did not happen in .NET Framework 4 since enum types in EF4 were not supported and cast operation would not cause loading types from the other assembly so for projects targeting .NET Framework 4 this is a regression in .NET
Framework 4.5. In EF6 the behavior will be the same regardless of .NET Framework version - we will always throw.
Did the work around provided by Decker work for you?
Please keep me in loop for the issue with anonymous types. If you create a new thread please post a link in this thread so that I get the notification and can look at it ASAP
Unfortunately, in my code base I can't change those type names that easily but it may be. What is strange is the type in the exception wasn't even used in the query. However, the enum that was used may have another enum with the same name in a different
assembly. So here is the link to the annonomous type issue. http://forums.asp.net/post/5233969.aspx
The cast to enum triggered loading types from the other assembly. When this happens EF will try to load all the types from the assembly and not only the one you are using. One of those types was conflicting and in the exception you see this type - even though
it is unrelated to your query .
bkotvis
Member
396 Points
83 Posts
.Net 4.5 upgrade (Schema specified is not valid)
Dec 06, 2012 04:29 PM|LINK
If you are using the Entity Framework and upgrade to .net 4.5 you may run into this problem. This one took me a while to figure out so I thought I would share what I found.
So I got a stack trace with the following message:
System.Data.MetadataException
Schema specified is not valid. Errors: The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'MultisiteSetting'. Previously found CLR type '...', newly found CLR type '...'.
This error made no sense because it the executing code had nothing to do with the types specified in the error message. After looking at this link , I saw that they added enum support in this version of the .net framework for the entity framework. So I looked at the linq query that was failing and noticed that I was sending enums into the where condition of the query. We almost never do this so the code caught my attention. Here is an example:
public enum PersonType { Good = 0, Bad = 1 } PersonType personType = PersonType.Bad; //PersonType column is an integer var query = from q in context.Persons where (PersonType)q.PersonType == personType select q; query.ToList();This will cause the exception provided above. Instead you can do this:
public enum PersonType { Good = 0, Bad = 1 } PersonType personType = PersonType.Bad; //PersonType column is an integer var query = from q in context.Persons where q.PersonType == (int)personType select q; query.ToList();Decker Dong ...
All-Star
118619 Points
18779 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 07, 2012 03:48 AM|LINK
Many thanks for sharing such a nice solution for us! Welcome to our fourm next time.
Reguards!
moozzyk
Member
10 Points
5 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 07, 2012 09:36 PM|LINK
Do you mind providing more details for this? Are you using CodeFirst? If so what version are you using? Can you provide the full stack trace and the full error message with type names? Do you by any chance have mulitple MultisiteSetting types (like entity and enum type) in different namespaces (and possibly in different assemblies). Can you show how the MulisiteSetting entity type looks like and how the entity used for context.Persons?
Having a repro would be awesome.
Thanks,
Pawel
bkotvis
Member
396 Points
83 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 08, 2012 09:40 PM|LINK
I can get the whole stack for you. I am not using code first. Just the POCO entities in EF 4.1. There are a couple classes with that name in different assemblies with this name, no enums just classes, however it appears to have nothing to do with the error. All you should need for the repro is what I provided. I may be able to send you a solution with a repro if you need it after getting this information. I actually have discovered another issue with annonomous types. Oh boy, it is a bad one. I will try to get some information up here about it when I have more information.
By the way, the context.Persons what just a bogus example. Here is the full stack:
System.Data.MetadataException: Schema specified is not valid. Errors:
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type '...'. Previously found CLR type '...', newly found CLR type '...'.
at System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, Boolean loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action`1 logLoadMessage)
at System.Data.Metadata.Edm.ObjectItemCollection.ImplicitLoadAssemblyForType(Type type, EdmItemCollection edmItemCollection)
at System.Data.Metadata.Edm.MetadataWorkspace.ImplicitLoadAssemblyForType(Type type, Assembly callingAssembly)
at System.Data.Objects.ELinq.ExpressionConverter.TryGetValueLayerType(Type linqType, TypeUsage& type)
at System.Data.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime)
at System.Data.Objects.ELinq.ExpressionConverter.ConvertTranslator.TranslateUnary(ExpressionConverter parent, UnaryExpression unary, DbExpression operand)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BitwiseBinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.NotTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression 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.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.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
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.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression 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.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
moozzyk
Member
10 Points
5 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 08, 2012 10:41 PM|LINK
Thanks for the stack trace. I found a similar issue on stackoverflow http://stackoverflow.com/questions/12114558/ef4-3-1-on-net-4-the-mapping-of-clr-type-to-edm-type-is-ambiguous-because-mul/13772969#13772969 and was able to repro. Symptoms and stack traces look the same. Here is my response to the thread on stack overflow:
I think I got to the bottom of it today.
It looks to me that the enum type lives in a separate assembly and the cast triggers loading types from this assembly. This assembly happen to contain the type 'DTO.A' which matches the 'Entities.A' type. This cause the ambiguity which in turn causes an exception to be thrown. Note that did not happen in .NET Framework 4 since enum types in EF4 were not supported and cast operation would not cause loading types from the other assembly so for projects targeting .NET Framework 4 this is a regression in .NET Framework 4.5. In EF6 the behavior will be the same regardless of .NET Framework version - we will always throw.
Did the work around provided by Decker work for you?
Please keep me in loop for the issue with anonymous types. If you create a new thread please post a link in this thread so that I get the notification and can look at it ASAP
Thanks,
Pawel
bkotvis
Member
396 Points
83 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 09, 2012 05:38 PM|LINK
Unfortunately, in my code base I can't change those type names that easily but it may be. What is strange is the type in the exception wasn't even used in the query. However, the enum that was used may have another enum with the same name in a different assembly. So here is the link to the annonomous type issue. http://forums.asp.net/post/5233969.aspx
moozzyk
Member
10 Points
5 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 10, 2012 04:32 PM|LINK
The cast to enum triggered loading types from the other assembly. When this happens EF will try to load all the types from the assembly and not only the one you are using. One of those types was conflicting and in the exception you see this type - even though it is unrelated to your query .
moozzyk
Member
10 Points
5 Posts
Re: .Net 4.5 upgrade (Schema specified is not valid)
Dec 17, 2012 10:10 PM|LINK
Just and update on this - we are considering addressing this in one of the future updates