Reputation: 1038
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
Upvotes: 87
Views: 99232
Reputation: 11
I wasn't able to get any of these solutions to work. I ended up saving the results of the stored procedure to a table then retrieved the data from there. I deleted all rows from the table at the beginning of the procedure.
Upvotes: 0
Reputation: 56
Open Model Browser and just rename Tables ona by one. After that update table names on your code.
Upvotes: 0
Reputation: 11
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>
Upvotes: 0
Reputation: 170
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.
Upvotes: 0
Reputation: 1
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; }
}
Upvotes: 0
Reputation: 516
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.
Upvotes: 0
Reputation: 11
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.
Upvotes: 1
Reputation: 13148
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
.
Upvotes: 0
Reputation: 755
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="data source=localhost;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" 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="data source=localhost;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I ended up copying the correct connection string from the EntitiesB's project's config file.
Upvotes: 2
Reputation: 1473
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.
Upvotes: 0
Reputation: 1880
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
Upvotes: 9
Reputation: 364249
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.
Upvotes: 79
Reputation: 7215
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.
Upvotes: 8
Reputation: 2303
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.
Upvotes: 1
Reputation: 3736
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.
Upvotes: 50
Reputation: 536
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>();
Upvotes: -9