The mapping of CLR type to EDM type is ambiguous with EF 6 & 5?

C#Entity FrameworkEntity Framework-4

C# Problem Overview


Please any one can help me to fix this error?

>Schema specified is not valid. Errors: > >The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'City_DAL'. Previously found CLR type 'CeossDAL.City_DAL', newly found CLR type 'CeossBLL.City_DAL'.

The main problem that I have DAL and this contains the EF and BLL and this contains the same classes of the DAL but differ in the namespace and this is what cause the problem

I can't know how to get rid of these problem, can you please help me?

Also I will be appreciated if some one give me sample to use n-tier architecture with EF

Thank you

C# Solutions


Solution 1 - C#

Don't use classes with the same unqualified name - EF uses only class names to identify the type mapped in EDMX (namespaces are ignored) - it is a convention to allow mapping classes from different namespaces to single model. The solution for your problem is to name your classes in BLL differently.

Solution 2 - C#

Workaround: Change a property on one of the two identical classes.

EF matches on class name AND class properties. So I just changed a property name on one of the EF objects, and the error is gone.

As @Entrodus commented on one of the other answers:

> EF collision happens only when two classes have the same name AND the > same set of parameters.

Solution 3 - C#

This MSDN forum question might be helpful. It suggest placing the BLL and DAL classes in separate assemblies.

Solution 4 - C#

In some cases this is more of a symptom than the actual problem. For me, it usually pops up when I try to call a function inside a Linq query without calling .ToList() first.

E.g. the error that brought me here was caused because I did this:

var vehicles = DB.Vehicles.Select(x => new QuickSearchResult()
{
    BodyText = x.Make + " " + x.Model + "<br/>"
    + "VIN: " + x.VIN + "<br/>"
    + "Reg: " + x.RegistrationNumber +"<br/>"
    + x.AdditionalInfo
    type = QuickSearchResultType.Vehicle,//HERE. Can't use an enum in an IQueryable.
    UniqueId = x.VehicleID
});

I had to call .ToList(), then iterate through each item and assign the type to it.

Solution 5 - C#

For EF 6.x, I found some notes at https://github.com/aspnet/EntityFramework/issues/941 and fixed this in my solution by adding annotation to the EDM type.

I edited the EDMX file manually and changed a line like this:

<EntityType Name="CartItem">

to this:

<EntityType Name="CartItem" customannotation:ClrType="EntityModel.CartItem">

or use this if you have existing type elsewhere:

<EntityType Name="CartItem" customannotation:ClrType="MyApp.CartItem, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">

where EntityModel is the namespace used for my EF model, and MyApp is the namespace of a business object

Solution 6 - C#

I got the error above because for both connection strings, I had the same value for metadata specified in my main project's config file, like below:

<add name="EntitiesA" connectionString="metadata=res://*/EntitiesA.csdl|res://*/EntitiesA.ssdl|res://*/EntitiesA.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

<add name="EntitiesB" connectionString="metadata=res://*/EntitiesA.csdl|res://*/EntitiesA.ssdl|res://*/EntitiesA.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

I ended up copying the correct connection string from the EntitiesB's project's config file.

Solution 7 - C#

This may not have been available when the question was asked, but another solution is to delete the EDMX and recreate it as a code-first entity data model. In EF6, with code-first, you can map two classes with the same name from different model namespaces without creating a conflict.

To create the entity data model in Visual Studio (2013), go to "Add" > "New Item..." > "ADO.NET Entity Data Model". Be sure to choose the "Code First from database" option.

Solution 8 - C#

Another reason you might get this error: If you're loading custom assemblies with Assembly.LoadFile that have edmx files, that have already been loaded into memory. This creates duplicate classes that entity framework doesn't like.

Solution 9 - C#

For me this was because I was attempting to access a type with the same name on the wrong context instance.

Say both ContextA and ContextB have SomeType. I was trying to access ContextA.SomeType on an instance of ContextB.

Solution 10 - C#

Just add the EntityFramework as "Code First from database" and not as "EF Designer from database". This resolved my problem, but it has a dark side, if you change your database you have to remove all the classes and add it again, or just edit the classes, I use the last when I change properties of the columns, like "Allows null" or the size of a string. But if you add columns I recomend remove and add again the classes.

Solution 11 - C#

I was able to solve this issue without renaming the classes, properties, or metadata.

I had my project setup with a T4 transform creating entity objects in a DAL project, and a T4 transform creating domain objects in a Domain project, both referencing the EDMX to generate identical objects, and then I was mapping the DAL objects to the Domain objects.

The error only occurred when I was referencing other classes (enums in my case) from the Domain assembly in my queries. When I removed them, the error went away. It looks like EF was loading up my Domain assembly because of this, seeing the other identically named classes, and blowing up.

To resolve this, I made a separate assembly that only contained my T4 transformed Domain classes. Since I never need to use these inside a query (only after the query to map to), I no longer have this issue. This seems cleaner and easier than the answers below.

Solution 12 - C#

if you have 2 connection string in web config but you want to use one connection string You use dynamic create connection string other entities. I have edmx(db first) and code first Entities in my solution. I use this class in Code first entities.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Data
{
	public class SingleConnection
	{
		private SingleConnection() { }
		private static SingleConnection _ConsString = null;
		private String _String = null;

		public static string ConString
		{
			get
			{
				if (_ConsString == null)
				{
					_ConsString = new SingleConnection { _String = SingleConnection.Connect() };
					return _ConsString._String;
				}
				else
					return _ConsString._String;
			}
		}

		public static string Connect()
		{
			string conString = ConfigurationManager.ConnectionStrings["YourConnectionStringsName"].ConnectionString;

			if (conString.ToLower().StartsWith("metadata="))
			{
				System.Data.Entity.Core.EntityClient.EntityConnectionStringBuilder efBuilder = new System.Data.Entity.Core.EntityClient.EntityConnectionStringBuilder(conString);
				conString = efBuilder.ProviderConnectionString;
			}

			SqlConnectionStringBuilder cns = new SqlConnectionStringBuilder(conString);
			string dataSource = cns.DataSource;
			SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
			{
				DataSource = cns.DataSource, // Server name
				InitialCatalog = cns.InitialCatalog,  //Database
				UserID = cns.UserID,         //Username
				Password = cns.Password,  //Password,
				MultipleActiveResultSets = true,
				ApplicationName = "EntityFramework",

			};
			//Build an Entity Framework connection string
			EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
			{
				Provider = "System.Data.SqlClient",
				Metadata = "res://*",
				ProviderConnectionString = sqlString.ToString()
			};
			return entityString.ConnectionString;
		}
	}
}

And when I call entities

private static DBEntities context
{
get
{
	if (_context == null)
		_context = new DBEntities(SingleConnection.ConString);

	return _context;

}
set { _context = value; }
}

Solution 13 - C#

I Think u Have a Class X named "MyClass" in Entity Models and Another Class Called "MyClass" in the same WorkFolder or Extended of the first Class. That is my problem and i fix it.

Solution 14 - C#

I found that using the custom annotation solution works with EF 6.2.0. Just make sure to change in the ConceptualModels node and use full namespace for the type.

<edmx:ConceptualModels>
  <Schema Namespace="Sample.Access.Data.Ef" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
    <EntityType Name="DbTableName" customannotation:ClrType="Sample.Access.Data.Ef.DbTableName, Sample.Access.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
      <Key>
        <PropertyRef Name="DbTableNameId" />
      </Key>
      <Property Name="DbTableNameId" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
      <Property Name="OptionName" Type="String" MaxLength="100" FixedLength="false" Unicode="false" Nullable="false" />
      <Property Name="Value" Type="String" MaxLength="500" FixedLength="false" Unicode="false" Nullable="false" />
      <Property Name="UpdatedDate" Type="DateTime" Nullable="false" Precision="3" />
    </EntityType>
    <EntityContainer Name="MyEntities" annotation:LazyLoadingEnabled="true" customannotation:UseClrTypes="true">
      <EntitySet Name="DbTableNames" EntityType="Self.DbTableName" />
    </EntityContainer>
  </Schema>
</edmx:ConceptualModels>

Solution 15 - C#

There is a library called AutoMapper which you can download. It helps you to define class mappings from one type to another.

Mapper.CreateMap<Model.FileHistoryEFModel, DataTypes.FileHistory>();
Mapper.CreateMap<DataTypes.FileHistory, Model.FileHistoryEFModel>();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMahmoud SamirView Question on Stackoverflow
Solution 1 - C#Ladislav MrnkaView Answer on Stackoverflow
Solution 2 - C#MattView Answer on Stackoverflow
Solution 3 - C#JarnoView Answer on Stackoverflow
Solution 4 - C#Captain KenpachiView Answer on Stackoverflow
Solution 5 - C#EkusView Answer on Stackoverflow
Solution 6 - C#Kristianne NeronaView Answer on Stackoverflow
Solution 7 - C#Tawab WakilView Answer on Stackoverflow
Solution 8 - C#ThomasView Answer on Stackoverflow
Solution 9 - C#Dave CousineauView Answer on Stackoverflow
Solution 10 - C#Felipe Batista SuardiView Answer on Stackoverflow
Solution 11 - C#CarsonView Answer on Stackoverflow
Solution 12 - C#Cetin SahinView Answer on Stackoverflow
Solution 13 - C#Maximiliano CesánView Answer on Stackoverflow
Solution 14 - C#Phi NguyenView Answer on Stackoverflow
Solution 15 - C#Pramod MangaloreView Answer on Stackoverflow