I am using EF6 with the database first approach. The database has three simple tables: Person, Token and Template
For the database I have generated the edmx model and entities
Person.cs
public partial class Person
{
public Person()
{
this.Tokens = new HashSet<Token>();
}
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PersonImage { get; set; }
public string Repository { get; set; }
public byte[] RepositoryHash { get; set; }
public virtual ICollection<Token> Tokens { get; set; }
}
Token.cs
public partial class Token
{
public long Id { get; set; }
public string TokenImage { get; set; }
public string NormalizedTokenImage { get; set; }
public long PersonId { get; set; }
public long TemplateId { get; set; }
public string TokenType { get; set; }
public string Repository { get; set; }
public byte[] RepositoryHash { get; set; }
public virtual Person Person { get; set; }
public virtual Template Template { get; set; }
}
Template.cs
public partial class Template
{
public Template()
{
this.Tokens = new HashSet<Token>();
}
public long Id { get; set; }
public string TemplateFile { get; set; }
public string TemplateType { get; set; }
public string Repository { get; set; }
public byte[] RepositoryHash { get; set; }
public virtual ICollection<Token> Tokens { get; set; }
}
The application is based on MEF and when needed it loads the DataProviderModule
that provides data using EF6. The application workflow is divided in two phases. Phase one initializes required modules and loads config for these modules. Then I create some data and save it with DataProviderModule
in database. Phase one ends here - so far so good.
When the Phase Two starts, I clear the old modules references and load new set of modules with the new instance of DataProviderModule
. But now, when I try to use EF inside the DataProviderModule
, the MetadataException is thrown (when I try to get data from database)
using (var entities = new Entities(_connectionString))
{
return entities.People.Count() // <-- MetadataException thrown here
}
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 'Person'.
Previously found CLR type 'MSSQLDBLib.Model.Person',
newly found CLR type 'MSSQLDBLib.Model.Person'.
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'Template'.
Previously found CLR type 'MSSQLDBLib.Model.Template',
newly found CLR type 'MSSQLDBLib.Model.Template'.
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'Token'.
Previously found CLR type 'MSSQLDBLib.Model.Token',
newly found CLR type 'MSSQLDBLib.Model.Token'.
StackTrace
at System.Data.Entity.Core.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(Assembly assembly, Boolean loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action`1 logLoadMessage)
at System.Data.Entity.Core.Metadata.Edm.ObjectItemCollection.ExplicitLoadFromAssembly(Assembly assembly, EdmItemCollection edmItemCollection, Action`1 logLoadMessage)
at System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace.ExplicitLoadFromAssembly(Assembly assembly, ObjectItemCollection collection, Action`1 logLoadMessage)
at System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace.LoadFromAssembly(Assembly assembly, Action`1 logLoadMessage)
at System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace.LoadFromAssembly(Assembly assembly)
at System.Data.Entity.Core.Metadata.Edm.MetadataOptimization.TryUpdateEntitySetMappingsForType(Type entityType)
at System.Data.Entity.Internal.InternalContext.TryUpdateEntitySetMappingsForType(Type entityType)
at System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType)
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
at System.Linq.Queryable.Count[TSource](IQueryable`1 source, Expression`1 predicate)
at MSSQLDBLib.MsSqlPersonalDataProvider.GetPersonsCount()
at DirectoryCompareApp.ViewModel.MainViewModel.<Start>d__5f.MoveNext() in d:\pzajic\SecufaceCollection\SecufaceNG\Sources\SecufaceNG\DirectoryCompareApp\ViewModel\MainViewModel.cs:line 810
I've already searched, how to solve this problem and I only found that same class names within different namespaces may cause similar problem, but this is not my case because the classes are in the same namespace.
Any advise will be greatly appreciated. Thank you.
After hours of desperate searching what’s wrong I finally found a solution. The problem is that I am composing MEF parts twice. Every time for each phase in my workflow and I think the same library is therefore loaded twice in the AppDomain. EF then sees two same classes in the same namespace.
The solution was very simple – in my code where I create assembly catalog and compose parts I need to add a flag to ensure this part is executed only once.