Ánh xạ loại CLR sang loại EDM không rõ ràng với EF 6 & 5?


75

Xin vui lòng bất kỳ ai có thể giúp tôi khắc phục lỗi này?

Lược đồ được chỉ định không hợp lệ. Các lỗi:

Việc ánh xạ loại CLR sang loại EDM không rõ ràng vì nhiều loại CLR khớp với loại EDM 'City_DAL'. Trước đây đã tìm thấy loại CLR 'CeossDAL.City_DAL', loại CLR mới được tìm thấy 'CeossBLL.City_DAL'.

Vấn đề chính là tôi có DAL và điều này chứa EF và BLL và điều này chứa cùng các lớp của DAL nhưng khác nhau về không gian tên và đây là nguyên nhân gây ra sự cố

Tôi không thể biết làm thế nào để thoát khỏi vấn đề này, bạn có thể vui lòng giúp tôi?

Ngoài ra, tôi sẽ được đánh giá cao nếu ai đó cho tôi mẫu để sử dụng kiến ​​trúc n-tier với EF

Cảm ơn bạn

Câu trả lời:


78

Không sử dụng các lớp có cùng tên không đủ tiêu chuẩn - EF chỉ sử dụng tên lớp để xác định kiểu được ánh xạ trong EDMX (không gian tên bị bỏ qua) - quy ước cho phép các lớp ánh xạ từ các không gian tên khác nhau thành một mô hình. Giải pháp cho vấn đề của bạn là đặt tên các lớp của bạn trong BLL theo cách khác.


Nếu tôi đặt tên các lớp trong BLL khác nhau, làm cách nào EF có thể ánh xạ giữa lớp của tôi trong DAL và BLL?
Mahmoud Samir

1
EF không ánh xạ giữa hai lớp. Nó ánh xạ giữa thực thể trong biểu đồ và tìm kiếm một lớp duy nhất có cùng tên.
Ladislav Mrnka

3
Tôi có hai lớp khi làm việc với một dự án có 3 lớp (DAL / BLL / PL), vì vậy tôi có EF trong DAL và tôi có các lớp EF giống nhau trong BLL, trong BLL mỗi lớp chứa các phương thức được sử dụng để gọi các phương thức từ DAL và các phương thức này trong DAL cần một đối tượng từ lớp Sản phẩm tồn tại trong DAL nhưng tôi gọi các phương thức này từ BLL, vì vậy khi tôi truyền đối tượng đó cho các phương thức DAL, tôi tạo một đối tượng từ Sản phẩm đó tồn tại trong BLL và ở đây ngoại lệ được nêu ra.
Mahmoud Samir

4
@Ladislav Tôi đã từ bỏ EF nếu không có bài đăng SO của bạn. Đã lưu lại. Cảm ơn bạn.
Neil Thompson

9
Xung đột EF chỉ xảy ra khi hai lớp có cùng tên VÀ cùng một bộ tham số.
Nikos Tsokos

42

Cách giải quyết: Thay đổi thuộc tính trên một trong hai lớp giống nhau.

EF khớp trên tên lớp VÀ thuộc tính lớp. Vì vậy, tôi vừa thay đổi tên thuộc tính trên một trong các đối tượng EF và lỗi đã biến mất.

Như @Entrodus đã nhận xét về một trong những câu trả lời khác:

Xung đột EF chỉ xảy ra khi hai lớp có cùng tên VÀ cùng một bộ tham số.


7
Đối với tiền của tôi, đây là câu trả lời tốt nhất - Tôi thà nhầm lẫn với một tên thuộc tính hơn là một tên lớp
Nổi bậtBill

2
Tôi chỉ cần đặt chúng trong hội đồng khác nhau .. không cần phải lộn xộn với điều này
Erik Bergstedt

6
@ErikBergstedt Nếu bạn sử dụng cả hai cụm trong cùng một giải pháp, bạn sẽ bắt đầu gặp lỗi.
Tundey

4
Trong Đối tượng xung đột trong EDMX, tôi đã thử thay đổi tên của một trong các thuộc tính, thêm một thuộc tính khác, thêm một lớp Phần có nhiều thuộc tính "dummy" hơn ... Cả hai đều không hoạt động. Chỉ thay đổi tên của Đối tượng làm việc cho tôi ...
Ymagine First

3
Đó là một câu nói vô nghĩa. Các lớp không có tham số.
Suncat2000

11

Câu hỏi diễn đàn MSDN này có thể hữu ích. Nó gợi ý đặt các lớp BLL và DAL trong các tập hợp riêng biệt.


2
Nếu bạn sử dụng cả hai cụm trong cùng một giải pháp, lỗi sẽ xảy ra ... Tôi có cùng một vấn đề. Cả hai đều là cơ sở dữ liệu khác nhau nhưng có cùng một tblSetting. Tôi đặt nó trên 2 cụm khác nhau (luôn được đặt lên lắp ráp khác nhau) và nó không làm việc :(
Sam

tôi đã sử dụng cả hai tập hợp trong cùng một giải pháp và lỗi không hiển thị nên tôi không biết chuyện gì đang xảy ra với nhận xét này ...
Niklas

8

Đối với EF 6.x, tôi đã tìm thấy một số ghi chú tại https://github.com/aspnet/EntityFramework/issues/941 và sửa lỗi này trong giải pháp của tôi bằng cách thêm chú thích vào loại EDM.

Tôi đã chỉnh sửa tệp EDMX theo cách thủ công và thay đổi một dòng như thế này:

<EntityType Name="CartItem">

đến điều này:

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

hoặc sử dụng cái này nếu bạn có loại hiện có ở nơi khác:

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

trong đó EntityModel là không gian tên được sử dụng cho mô hình EF của tôi và MyApp là không gian tên của một đối tượng nghiệp vụ


1
Điều này đã không làm việc cho tôi (cố gắng EF 6.0 và 6.3), làm việc với cơ sở dữ liệu SQLite
Daniel Tulp

:-( Tôi chỉ sử dụng nó với MSSQL
Ekus

1
Bài đăng trên Github đó cũng cho biết thêm customannotation:UseClrTypesvào <EntityContainer>. (Vẫn không hiệu quả với tôi trong EF 6)
Keith

1
Nó hoạt động với tôi với MSSQL và EF 6.3.0 (chưa thử nghiệm các kết hợp khác).
Peter Ivan

6

Trong một số trường hợp, đây là một triệu chứng hơn là một vấn đề thực tế. Đối với tôi, nó thường bật lên khi tôi cố gắng gọi một hàm bên trong truy vấn Linq mà không gọi .ToList () trước.

Ví dụ: lỗi đưa tôi đến đây là do tôi đã làm điều này:

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
});

Tôi phải gọi .ToList (), sau đó lặp lại từng mục và gán kiểu cho nó.


2
Cảm ơn bạn! Đây chính xác là vấn đề của tôi, truyền tới một enum trong câu lệnh linq.
Doug

1

Điều này có thể không khả dụng khi câu hỏi được đặt ra, nhưng một giải pháp khác là xóa EDMX và tạo lại nó dưới dạng mô hình dữ liệu thực thể đầu mã. Trong EF6, với phần đầu mã, bạn có thể ánh xạ hai lớp có cùng tên từ các không gian tên mô hình khác nhau mà không tạo ra xung đột.

Để tạo mô hình dữ liệu thực thể trong Visual Studio (2013), hãy đi tới "Thêm"> "Mục mới ..."> "Mô hình dữ liệu thực thể ADO.NET". Đảm bảo chọn tùy chọn "Mã đầu tiên từ cơ sở dữ liệu".


Điều này đã không làm việc cho tôi (cố gắng EF 6.0 và 6.3), làm việc với cơ sở dữ liệu SQLite
Daniel Tulp

Tôi không biết liệu nó có tạo ra sự khác biệt hay không, nhưng tôi đã sử dụng MS SQL Server khi thực hiện việc này.
Tawab Wakil

Điều này hoàn toàn làm việc cho tôi. Tôi có một tình huống mà dường như không có giải pháp nào khác áp dụng được.
Dave

Đó là bởi vì các loại thực thể được chú thích khác nhau cho Code First. Xem câu trả lời của @ Ekus tại stackoverflow.com/a/44931349/1307074 .
Suncat2000,

1

Tôi gặp lỗi ở trên vì đối với cả hai chuỗi kết nối, tôi có cùng một giá trị cho siêu dữ liệu được chỉ định trong tệp cấu hình của dự án chính của tôi, như bên dưới:

<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" />

Tôi đã kết thúc việc sao chép đúng chuỗi kết nối từ tệp cấu hình của dự án EntitiesB.


Tôi nghĩ OP có vấn đề với tên thực thể tên. Tôi cũng vậy ... Tôi đã đặt đúng chuỗi kết nối trong Web.config của mình. Nó vẫn không hoạt động :(
Sam

Đã khắc phục sự cố sau khi xem câu trả lời của bạn và dành 3 giờ để tìm hiểu.
ChupChapCharli

0

Một lý do khác khiến bạn có thể gặp lỗi này: Nếu bạn đang tải các hội đồng tùy chỉnh với Assembly.LoadFile có các tệp edmx, đã được tải vào bộ nhớ. Điều này tạo ra các lớp trùng lặp mà khung thực thể không thích.


0

Đối với tôi, điều này là do tôi đã cố gắng truy cập một loại có cùng tên trên phiên bản ngữ cảnh sai.

Nói cả hai ContextAContextBSomeType. Tôi đã cố gắng truy cập ContextA.SomeTypevào một phiên bản của ContextB.


0

Chỉ cần thêm EntityFramework là "Code First from database" chứ không phải "EF Designer từ database". Điều này đã giải quyết được vấn đề của tôi, nhưng nó có mặt tối, nếu bạn thay đổi cơ sở dữ liệu của mình, bạn phải xóa tất cả các lớp và thêm lại hoặc chỉ chỉnh sửa các lớp, tôi sử dụng cuối cùng khi tôi thay đổi thuộc tính của các cột, như "Cho phép null "hoặc kích thước của một chuỗi. Nhưng nếu bạn thêm cột, tôi khuyên bạn nên xóa và thêm lại các lớp.


0

Tôi đã có thể giải quyết vấn đề này mà không cần đổi tên các lớp, thuộc tính hoặc siêu dữ liệu.

Tôi đã thiết lập dự án của mình với biến đổi T4 tạo các đối tượng thực thể trong dự án DAL và biến đổi T4 tạo các đối tượng miền trong dự án Miền, cả hai đều tham chiếu EDMX để tạo các đối tượng giống nhau và sau đó tôi đang ánh xạ các đối tượng DAL với các đối tượng Miền .

Lỗi chỉ xảy ra khi tôi tham chiếu đến các lớp khác (trong trường hợp của tôi là enums) từ hợp ngữ Miền trong các truy vấn của mình. Khi tôi xóa chúng, lỗi đã biến mất. Có vẻ như EF đang tải tập hợp Miền của tôi vì điều này, nhìn thấy các lớp khác được đặt tên giống nhau và nổ tung.

Để giải quyết vấn đề này, tôi đã tạo một assembly riêng chỉ chứa các lớp Miền được chuyển đổi T4 của tôi. Vì tôi không bao giờ cần sử dụng những thứ này bên trong một truy vấn (chỉ sau truy vấn để ánh xạ tới), tôi không còn gặp vấn đề này nữa. Điều này có vẻ rõ ràng và dễ dàng hơn các câu trả lời dưới đây.


0

nếu bạn có 2 chuỗi kết nối trong cấu hình web nhưng bạn muốn sử dụng một chuỗi kết nối Bạn sử dụng động tạo chuỗi kết nối các thực thể khác. Tôi có edmx (db trước) và mã các Thực thể đầu tiên trong giải pháp của mình. Tôi sử dụng lớp này trong các thực thể đầu tiên của Mã.

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;
        }
    }
}

Và khi tôi gọi các thực thể

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

    return _context;

}
set { _context = value; }
}

0

Tôi nghĩ bạn Có một Lớp X có tên "MyClass" trong Mô hình Thực thể và Một Lớp khác được gọi là "MyClass" trong cùng WorkFolder hoặc Extended của Lớp đầu tiên. Đó là vấn đề của tôi và tôi sửa chữa nó.


-9

Có một thư viện tên là AutoMapper mà bạn có thể tải xuống. Nó giúp bạn xác định ánh xạ lớp từ kiểu này sang kiểu khác.

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

12
không thực sự áp dụng cho câu hỏi của người dùng. Sử dụng automapper sẽ không chỉ khắc phục được sự cố của anh ấy.
Calvin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.