I have an IIS-enabled WCF service that connects to an SQL database database using Entity Framework 4.1. Sometimes I get the following exception:
EdmType cannot be mapped to CLR classes multiple times. EdmType 'Model.EmailTemplate' is displayed more than once. (An item with the same key has already been added.)
This rarely happens, so I'm not sure that it was always the same class, but definitely nothing special in the class mentioned above, and it definitely doesn't appear in edmx more than once! (I believe this simply blames the first class, which it tries to access after what happens when it sends the Entity Framework off the rails.)
A model is created from database tables using a constructor and does not have any complex mappings or anything else.
When this happens, it will continue to throw this exception until I make an iisreset, and then when it returns, it will be completely happy.
It seems that this does not happen in production, as far as I know, but it happens both in dev and in test mode, in two different environments with different instances of the SQL server. In both cases, running iisreset forces him to leave until the next time he is offended.
I cannot reproduce it sequentially enough to be sure when it will happen and what causes it. However, I can think of two possible things:
The WCF service and win32 service share the same builds and configuration files to connect to the same database. I suppose this may be some random combination of time between the two of them, one of them is annoying, but they are different processes and use different credentials, so I'm not sure how they can affect each other ...
There is a point at which it speaks to a second separate database on which it calls some stored procedures using SqlCommand.ExecuteReader
. It creates an EF context just to call ObjectContext.Translate<ResultSetType>(reader)
. The types of the result set that are called as common parameters are not types that are displayed in the context (and, in particular, nothing to do with the type mentioned in the above exception), it's just POCO. They also do not connect to the same database as the object context, since the corresponding SqlDataReader is already ready for rolling. An object context is simply used as a convenient way to automatically transfer objects from another database. (This call would be static if there was a static Translate<T>(DbDataReader)
.) This is probably what disables it, as it is a bit hacked and probably doesn't appreciate being used that way ... but the block is wrapped in using (with TransactionScopeOption.Suppress, using directly inside it), so I still feel that I should not have this effect for subsequent calls made with other contexts created later ...
Has anyone ever come across something like this?
Edited to add: This is a MappingException, and the stacktrace value is lower.
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.CreateCastExpression(DbExpression source, Type toClrType, Type fromClrType) 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.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression 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.SelectTranslator.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.Collections.ObjectModel.ObservableCollection`1.CopyFrom(IEnumerable`1 collection) at System.Collections.ObjectModel.ObservableCollection`1..ctor(IEnumerable`1 collection)