CLR 유형과 EDM 유형의 매핑은 EF 6 & 5에서 모호합니다.
누구든지이 오류를 수정하는 데 도움을 줄 수 있습니까?
지정된 스키마가 유효하지 않습니다. 오류 :
여러 CLR 유형이 EDM 유형 'City_DAL'과 일치하므로 CLR 유형과 EDM 유형의 매핑이 모호합니다. 이전에 발견 된 CLR 유형 'CeossDAL.City_DAL', 새로 발견 된 CLR 유형 'CeossBLL.City_DAL'.
내가 DAL을 가지고 있고 이것은 EF와 BLL을 포함하고 이것은 DAL의 동일한 클래스를 포함하지만 네임 스페이스가 다르며 이것이 문제의 원인이되는 주요 문제입니다.
이 문제를 해결하는 방법을 모르겠습니다. 도와 주시겠습니까?
또한 누군가가 EF와 함께 n 계층 아키텍처를 사용하기 위해 샘플을 제공하면 감사하겠습니다.
감사합니다
동일한 정규화되지 않은 이름을 가진 클래스를 사용하지 마십시오. EF는 EDMX에 매핑 된 유형을 식별하기 위해 클래스 이름 만 사용합니다 (네임 스페이스는 무시 됨). 다른 네임 스페이스의 클래스를 단일 모델로 매핑하는 것은 규칙입니다. 문제에 대한 해결책은 BLL의 클래스 이름을 다르게 지정하는 것입니다.
해결 방법 : 동일한 두 클래스 중 하나에서 속성을 변경합니다.
EF는 클래스 이름 및 클래스 속성과 일치합니다. 그래서 방금 EF 개체 중 하나에서 속성 이름을 변경했는데 오류가 사라졌습니다.
@Entrodus가 다른 답변 중 하나에 대해 언급했듯이 :
EF 충돌은 두 클래스가 동일한 이름과 동일한 매개 변수 집합을 가질 때만 발생합니다.
이 MSDN 포럼 질문이 도움이 될 수 있습니다. BLL 및 DAL 클래스를 별도의 어셈블리에 배치하는 것이 좋습니다.
EF 6.x의 경우 https://github.com/aspnet/EntityFramework/issues/941 에서 몇 가지 메모를 발견 하고 EDM 유형에 주석을 추가하여 솔루션에서이 문제를 해결했습니다.
EDMX 파일을 수동으로 편집하고 다음 과 같은 줄을 변경했습니다.
<EntityType Name="CartItem">
이에:
<EntityType Name="CartItem" customannotation:ClrType="EntityModel.CartItem">
또는 다른 곳에 기존 유형이있는 경우 이것을 사용하십시오.
<EntityType Name="CartItem" customannotation:ClrType="MyApp.CartItem, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
여기서 EntityModel 은 내 EF 모델에 사용되는 네임 스페이스이고 MyApp 은 비즈니스 오브젝트의 네임 스페이스입니다.
어떤 경우에는 이것은 실제 문제보다 더 많은 증상입니다. 나를 위해 .ToList ()를 먼저 호출하지 않고 Linq 쿼리 내에서 함수를 호출하려고 할 때 일반적으로 나타납니다.
예를 들어 나를 여기로 가져온 오류는 내가 이것을했기 때문에 발생했습니다.
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
});
.ToList ()를 호출 한 다음 각 항목을 반복하고 유형을 할당해야했습니다.
질문을 받았을 때 사용할 수 없었을 수도 있지만 또 다른 해결책은 EDMX를 삭제하고 코드 우선 엔티티 데이터 모델로 다시 만드는 것입니다. EF6에서는 코드 우선을 사용하여 충돌을 일으키지 않고 서로 다른 모델 네임 스페이스의 동일한 이름을 가진 두 클래스를 매핑 할 수 있습니다.
Visual Studio (2013)에서 엔터티 데이터 모델을 만들려면 "추가"> "새 항목 ..."> "ADO.NET 엔터티 데이터 모델"로 이동합니다. "데이터베이스에서 코드 우선"옵션을 선택해야합니다.
이 오류가 발생할 수있는 또 다른 이유 : 이미 메모리에로드 된 edmx 파일이있는 Assembly.LoadFile을 사용하여 사용자 지정 어셈블리를로드하는 경우입니다. 이것은 엔티티 프레임 워크가 좋아하지 않는 중복 클래스를 생성합니다.
두 연결 문자열 모두에 대해 아래와 같이 기본 프로젝트의 구성 파일에 지정된 메타 데이터에 대해 동일한 값이 있기 때문에 위의 오류가 발생했습니다.
<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" />
결국 EntitiesB의 프로젝트 구성 파일에서 올바른 연결 문자열을 복사했습니다.
나에게 이것은 잘못된 컨텍스트 인스턴스에서 동일한 이름을 가진 유형에 액세스하려고 시도했기 때문입니다.
둘 다 말 ContextA
하고 ContextB
있습니다 SomeType
. ContextA.SomeType
의 인스턴스에 액세스하려고했습니다 ContextB
.
EntityFramework를 "데이터베이스의 EF 디자이너"가 아닌 "데이터베이스의 코드 우선"으로 추가하면됩니다. 이것은 내 문제를 해결했지만 어두운면이 있습니다. 데이터베이스를 변경하면 모든 클래스를 제거하고 다시 추가하거나 클래스를 편집해야합니다. "허용"과 같은 열의 속성을 변경할 때 마지막을 사용합니다. null "또는 문자열의 크기. 그러나 열을 추가하면 클래스를 제거하고 다시 추가하는 것이 좋습니다.
클래스, 속성 또는 메타 데이터의 이름을 바꾸지 않고도이 문제를 해결할 수있었습니다.
DAL 프로젝트에서 엔터티 개체를 만드는 T4 변환과 도메인 프로젝트에서 도메인 개체를 만드는 T4 변환으로 프로젝트를 설정했습니다. 둘 다 EDMX를 참조하여 동일한 개체를 생성 한 다음 DAL 개체를 Domain 개체에 매핑했습니다. .
이 오류는 쿼리에서 Domain 어셈블리의 다른 클래스 (내 경우에는 열거 형)를 참조 할 때만 발생했습니다. 제거했을 때 오류가 사라졌습니다. 이 때문에 EF가 도메인 어셈블리를로드하고 동일한 이름의 다른 클래스를보고 폭파하는 것처럼 보입니다.
이 문제를 해결하기 위해 T4 변환 도메인 클래스 만 포함하는 별도의 어셈블리를 만들었습니다. 쿼리 내에서 사용할 필요가 없기 때문에 (매핑 할 쿼리 후에 만) 더 이상이 문제가 발생하지 않습니다. 이것은 아래 답변보다 깨끗하고 쉽습니다.
웹 구성에 2 개의 연결 문자열이 있지만 하나의 연결 문자열을 사용하려는 경우 동적 생성 연결 문자열 다른 엔터티를 사용합니다. 내 솔루션에서 edmx (db first) 및 코드 첫 번째 엔터티가 있습니다. 이 클래스는 Code first 엔터티에서 사용합니다.
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;
}
}
}
그리고 엔티티를 호출 할 때
private static DBEntities context
{
get
{
if (_context == null)
_context = new DBEntities(SingleConnection.ConString);
return _context;
}
set { _context = value; }
}
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.
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>();
'programing tip' 카테고리의 다른 글
svn 브랜치와 태그를 git-svn으로 가져 오는 방법은 무엇입니까? (0) | 2020.11.11 |
---|---|
'less'명령을 사용하는 동안 Unix에서 특수 문자 표시 (0) | 2020.11.11 |
특정 월의 모든 레코드를 찾는 WHERE 절 (0) | 2020.11.10 |
git 저장소를 복제하는 Python 방법 (0) | 2020.11.10 |
Apache에서 인코딩 된 슬래시를 허용해야합니다. (0) | 2020.11.10 |