2009-03-31 26 views
22

Tôi có một sự tách biệt hoàn toàn của đối tượng Entity Framework tôi và các đối tượng POCO của tôi, tôi chỉ dịch chúng qua lại ...Làm cách nào để đính kèm đối tượng Khung thực thể không phải từ cơ sở dữ liệu?

ví dụ:

// poco 
public class Author 
{ 
    public Guid Id { get; set; } 
    public string UserName { get; set; } 
} 

và sau đó tôi có một đối tượng EF "Tác giả" với tính chất tương tự ..

vì vậy, tôi có tôi đối tượng kinh doanh

var author = new Author { UserName="foo", Id="Guid thats in the db" }; 

và tôi muốn lưu đối tượng này vì vậy tôi làm follo cánh:

var dbAuthor = new dbAuthor { Id=author.Id, UserName=author.UserName }; 
entities.Attach(dbAuthor); 
entities.SaveChanges(); 

nhưng điều này mang lại cho tôi những lỗi sau:

An object with a null EntityKey value cannot be attached to an object context.

EDIT: Dường như tôi phải sử dụng entities.AttachTo ("Tác giả", dbAuthor); để đính kèm mà không có một EntityKey, nhưng sau đó tôi có các chuỗi ma thuật mã hóa cứng, sẽ phá vỡ nếu tôi thay đổi thực thể của tôi đặt tên ở tất cả và tôi sẽ không có bất kỳ kiểm tra thời gian biên dịch ... Có cách nào tôi có thể đính kèm mà giữ thời gian biên dịch kiểm tra ?

Tôi hy vọng tôi có thể làm được điều này, như dây cứng được mã hóa giết chết xác nhận thời gian biên dịch sẽ hút =)

+0

Bạn có nhìn vào sửa đổi cho câu trả lời của tôi, nó sẽ cho phép y ou để làm điều đó mà không có chuỗi ma thuật hoặc AttachTo vì các phương thức được thiết kế tạo ra và duy trì bởi mô hình edmx. –

+0

Có, tôi không thêm nó, tôi đang cập nhật nó, vì vậy tôi cần phải đính kèm nó, và lưu thay đổi – sontek

+0

Tôi vẫn tin rằng mô hình của bạn có vấn đề với thuộc tính Id trên đối tượng Tác giả không được đặt làm EntityKey , bạn nên kiểm tra kỹ XML đã tạo và đảm bảo rằng nó được lồng trong phần tử khóa và đảm bảo thuộc tính Id có thuộc tính EdmScalarPropertyAttribute (EntityKeyProperty = true) –

Trả lời

13

Bạn đã cố gắng sử dụng AttachTo và xác định các thiết lập tổ chức? ..

entities.AttachTo("Authors", dbAuthor); 

trong đó "Authors" sẽ là tên tập hợp thực thể thực của bạn.

Chỉnh sửa:
Có cách nào tốt hơn (cũng nên có). Các nhà thiết kế nên đã tạo ra "Add" methods để ObjectContext cho bạn mà dịch ra lời kêu gọi trên .. Vì vậy, bạn sẽ có thể làm:

entities.AddToAuthors(dbAuthor); 

mà theo nghĩa đen nên là:

public void AddToAuthors(Authors authors) 
{ 
    base.AddObject("Authors", authors); 
} 

định nghĩa trong tệp whateverobjectcontext.designer.cs.

+4

Điều này dường như làm việc, nhưng sau đó tôi có "chuỗi ma thuật" ở mọi nơi, và nếu tôi đổi tên thực thể thiết lập tất cả các mã của tôi sẽ phá vỡ. Có cách nào tốt hơn để làm điều này? – sontek

+0

@Ashkan Chỉnh sửa của bạn làm cho câu trả lời sai, 'AddToAuthors' được tạo tự động không sử dụng' EntitySet.Name' và chỉnh sửa của bạn xác nhận quyền sở hữu, vì vậy tôi đã hoàn nguyên. Nguyên tắc đằng sau chỉnh sửa của bạn có vẻ tốt với tôi, và đó là những gì được sử dụng trong câu trả lời khác, mà tôi đã upvoted, và tôi khuyến khích bạn làm như vậy. – hvd

15

Vừa xem mục này ngay bây giờ. Nếu bạn muốn Đính kèm() để ObjectContext, tức là thuyết phục các khuôn khổ thực thể mà một thực thể tồn tại trong cơ sở dữ liệu đã có, và bạn muốn tránh sử dụng dây ma thuật tức là

ctx.AttachTo("EntitySet", entity); 

Bạn có thể thử hai khả năng dựa trên phương pháp khuyến nông , cả hai điều này chắc chắn làm cho cuộc sống trở nên dễ chịu hơn.

Tùy chọn đầu tiên cho phép bạn viết:

ctx.AttachToDefault(entity); 

và được bao phủ ở đây: Tip 13 - How to attach an entity the easy way

Lựa chọn thứ hai cho phép bạn viết:

ctx.EntitySet.Attach(entity); 

và được bao phủ ở đây: Tip 16 - How to mimic .NET 4.0's ObjectSet today

Như bạn có thể thấy cả hai thực sự dễ sử dụng và tránh chuỗi hoàn toàn.

Hope this helps

Alex

-2

Đối với tôi,

Context.Authors.AddObject(new Author()) 

tác phẩm hoàn hảo. Tự hỏi nếu tôi đang thiếu một cái gì đó? Hay đó không phải là cách đúng đắn?

+4

Điều này được sử dụng cho các đối tượng mới, không được sử dụng cho các đối tượng hiện có. – ReinierDG

5

Hãy thử điều này nếu bạn không muốn viết chuỗi với tên EntitySet

entities.AttachTo(entities.CreateObjectSet<T>().EntitySet.Name, entity); 
+0

'entity.Authors.Attach (dbAuthor);' là đẹp hơn. – ReinierDG

+0

Tôi đã sử dụng mã của mình theo phương pháp chung, nơi tôi có thể gat bất kỳ loại đối tượng nào ... – sebagomez

0

Bạn có thể thử sau

entities.AddToAuthors(dbAuthor); 
+1

Đây thực sự là một bình luận, không phải là câu trả lời cho câu hỏi. Bạn luôn có thể nhận xét về bài đăng của riêng mình và khi bạn có đủ [danh tiếng] (http://stackoverflow.com/faq#reputation), bạn sẽ có thể [nhận xét về bất kỳ bài đăng nào] (http://stackoverflow.com/ đặc quyền/bình luận). –

+1

@BryanCrosby Tôi không đồng ý. Tôi tin rằng đây là một câu trả lời, không phải là một bình luận. – mayu

4

một sự thay thế cho điều này là như sau đặc biệt là nếu bạn don Không biết thực thể nào bạn sẽ hoạt động trên:

string className = entityObject.GetType().Name; 
var container = _DbContext.MetadataWorkspace.GetEntityContainer(_DbContext.DefaultContainerName, DataSpace.CSpace); 
string setName = (from meta in container.BaseEntitySets 
        where meta.ElementType.Name == className 
        select meta.Name).First(); 
_DbContext.AttachTo(setName, entityObject); 
+0

Cảm ơn bạn vì điều này, không có ý tưởng làm thế nào bạn figured này ra nhưng tôi đã xảy ra để chạy qua nó khi tìm kiếm một cách để làm chính xác điều này. Tôi đang sử dụng dự án Thủ tục lưu trữ mã đầu tiên từ https://www.codeproject.com/articles/179481/code-first-stored-procedures và không hài lòng khi các mục không được thêm vào theo dõi DbContext. Sử dụng mã này, tôi đã có thể thêm chúng. Nó không hoàn hảo bởi vì chúng được thêm vào mà không có mã proxy để tải thuộc tính lười biếng, nhưng nó hoạt động tốt đủ cho tôi. – Brad

Các vấn đề liên quan