S'il vous plaît, tout le monde peut m'aider à corriger cette erreur?
Le schéma spécifié n'est pas valide. Les erreurs:
Le mappage du type CLR sur le type EDM est ambigu, car plusieurs types de CLR correspondent au type EDM 'City_DAL'. Type CLR précédemment trouvé 'CeossDAL.City_DAL', type CLR nouvellement trouvé 'CeossBLL.City_DAL'.
Le problème principal que j'ai DAL et cela contient les EF et BLL et cela contient les mêmes classes du DAL mais diffère dans l'espace de noms et c'est ce qui cause le problème
Je ne sais pas comment me débarrasser de ce problème, pouvez-vous m'aider s'il vous plaît?
J'apprécierais aussi si quelqu'un me donnait un exemple d'utilisation de l'architecture n-tier avec EF
Je vous remercie
N'utilisez pas de classes avec le même unqualified name - EF utilise uniquement des noms de classe pour identifier le type mappé dans EDMX (les espaces de nom sont ignorés). Il s'agit d'une convention permettant d'autoriser le mappage de classes de différents espaces de nom sur un seul modèle. La solution à votre problème consiste à nommer vos classes dans BLL différemment.
Solution: modifiez une propriété sur l'une des deux classes identiques.
EF correspond au nom de la classe ET aux propriétés de la classe. Je viens donc de changer un nom de propriété sur l'un des objets EF, et l'erreur a disparu.
Comme @Entrodus a commenté l'une des autres réponses:
La collision EF ne se produit que lorsque deux classes ont le même nom ET le même ensemble de paramètres.
Cette question sur le forum MSDN pourrait être utile. Il suggère de placer les classes BLL et DAL dans des assemblys séparés.
Pour EF 6.x, j'ai trouvé des notes sur https://github.com/aspnet/EntityFramework/issues/941 et j'ai résolu ce problème dans ma solution en ajoutant une annotation au type EDM.
J'ai édité le fichier EDMX manuellement et modifié une ligne comme ceci:
<EntityType Name="CartItem">
pour ça:
<EntityType Name="CartItem" customannotation:ClrType="EntityModel.CartItem">
ou utilisez ceci si vous avez un type existant ailleurs:
<EntityType Name="CartItem" customannotation:ClrType="MyApp.CartItem, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
où EntityModel est l'espace de nom utilisé pour mon modèle EF et MyApp est l'espace de nom d'un objet métier
Dans certains cas, il s'agit davantage d'un symptôme que du problème réel. Pour moi, il apparaît généralement lorsque j'essaie d'appeler une fonction dans une requête Linq sans appeler .ToList () auparavant.
Par exemple. l'erreur qui m'a amené ici a été causée parce que j'ai fait ceci:
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
});
J'ai dû appeler .ToList (), puis parcourir chaque élément et lui attribuer le type.
Cela n'était peut-être pas disponible lorsque la question a été posée, mais une autre solution consiste à supprimer l'EDMX et à le recréer en tant que modèle de données d'entité premier code. Dans EF6, avec le code d'abord, vous pouvez mapper deux classes portant le même nom à partir d'espaces de nom de modèle différents sans créer de conflit.
Pour créer le modèle de données d'entité dans Visual Studio (2013), accédez à "Ajouter"> "Nouvel élément ..."> "Modèle de données d'entité ADO.NET". Assurez-vous de choisir l'option "Code d'abord de la base de données".
Je pense que vous avez une classe X nommée "MyClass" dans Entity Models et une autre classe appelée "MyClass" dans le même dossier de travail ou étendu de la première classe . C'est mon problème et je le répare.
J'ai pu résoudre ce problème sans renommer les classes, propriétés ou métadonnées.
J'avais configuré mon projet avec une transformation T4 créant des objets d'entité dans un projet DAL et une transformation T4 créant des objets de domaine dans un projet de domaine, faisant tous deux référence à EDMX pour générer des objets identiques, puis je mappais les objets DAL aux objets de domaine. .
L'erreur s'est produite uniquement lorsque je faisais référence à d'autres classes (énumérations dans mon cas) de l'assembly de domaine dans mes requêtes. Quand je les ai enlevés, l'erreur est partie. Il semblerait que EF chargeait mon Domain Domain à cause de cela, voyant les autres classes portant le même nom et explosant.
Pour résoudre ce problème, j'ai créé un assembly séparé contenant uniquement les classes de domaine transformées T4. Comme je n'ai jamais besoin de les utiliser dans une requête (uniquement après la requête à mapper), je n'ai plus ce problème. Cela semble plus propre et plus facile que les réponses ci-dessous.
J'ai eu l'erreur ci-dessus car pour les deux chaînes de connexion, j'avais la même valeur pour les métadonnées spécifiées dans le fichier de configuration de mon projet principal, comme ci-dessous:
<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" />
J'ai fini par copier la chaîne de connexion correcte à partir du fichier de configuration du projet EntitiesB.
Pour moi, c'était parce que j'essayais d'accéder à un type portant le même nom sur la mauvaise instance de contexte.
Dites que ContextA
et ContextB
ont SomeType
. J'essayais d'accéder à ContextA.SomeType
sur une instance de ContextB
.
si vous avez deux chaînes de connexion dans Web Config mais que vous souhaitez utiliser une chaîne de connexion Vous utilisez une chaîne de connexion dynamique pour créer d'autres entités. J'utilise cette classe dans les premières entités de code.
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;
}
}
}
Et quand j'appelle des entités
private static DBEntities context
{
get
{
if (_context == null)
_context = new DBEntities(SingleConnection.ConString);
return _context;
}
set { _context = value; }
}
Ajoutez simplement EntityFramework en tant que "Code premier de la base de données" et non en tant que "Concepteur EF de la base de données". Cela a résolu mon problème, mais il a un côté sombre. Si vous modifiez votre base de données, vous devez supprimer toutes les classes et l'ajouter à nouveau, ou simplement modifier les classes. null "ou la taille d'une chaîne. Mais si vous ajoutez des colonnes, je vous recommande de supprimer et d’ajouter les classes.
Une autre raison peut être l’erreur suivante: Si vous chargez des assemblys personnalisés avec Assembly.LoadFile contenant des fichiers edmx, ceux-ci ont déjà été chargés en mémoire. Cela crée des classes en double que le framework d'entité n'aime pas.