2011-08-02 5 views
14

Câu trả lời tôi thấy ở đây là dành cho ObjectContext. Có một tài sản để xác định tên khóa chính của một thực thể khi sử dụng DbContext?Cách lấy (các) Khoá chính trong Khung thực thể 4.1, tức là sử dụng DbContext

Ah .. một trong những thời điểm mà tôi muốn Khung thực thể là nguồn mở! Tôi có thể thu thập thông tin về tên khóa chính này từ phương pháp .find :-)

+1

Bạn có thể xem mã nguồn tại http://entityframework.codeplex.com/ – VahidNaderi

Trả lời

26

Bạn không thể sử dụng DbContext cho điều đó - DbContext API chỉ là trình bao bọc câm chỉ với chức năng cần thiết nhất. Đối với mọi thứ phức tạp hơn, bạn phải chuyển đổi DbContext trở lại ObjectContext và sử dụng nó. Hãy thử một cái gì đó như thế này:

Extract tên chính:

public static string[] GetEntityKeyNames<TEntity>(this DbContext context) where TEntity : class 
{ 
    if (context == null) 
    throw new ArgumentNullException("context"); 

    var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>(); 
    var entitySet = set.EntitySet; 
    return entitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray(); 
} 

Dưới đây là một phương pháp cho phép trích xuất các giá trị chính của một thực thể:

public static IEnumerable<object> GetEntityKeys<TEntity>(this DbContext context, TEntity entity) 
    where TEntity : class 
{ 
    if (context == null) 
    throw new NullReferenceException("context"); 

    var type = typeof(TEntity); 

    var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>(); 
    var entitySet = set.EntitySet; 
    var keys = entitySet.ElementType.KeyMembers; 
    var props = keys.Select(k => type.GetProperty(k.Name)); 
    return props.Select(p => p.GetValue(entity)); 
} 
+0

đã hoạt động ... một lần nữa bài đăng Lad đã giúp tôi thx +1 –

+2

Tôi không nghĩ điều này sẽ làm việc nếu TEntity có nguồn gốc lớp.Có cách nào để làm điều này mà không cần CreateObjectSet ? –

+2

Trong trường hợp bất kỳ ai khác cố gắng này (EF 6) và nhận được thông báo cho biết: Loại 'TEntity' phải là một kiểu tham chiếu để sử dụng nó làm tham số ... nó yêu cầu ràng buộc 'TEntity: class'. Chữ ký CreateObjectSet và def: http://msdn.microsoft.com/en-us/library/dn236948%28v=vs.113%29.aspx –

1
+0

tôi đã biết rằng (' (db như IObjectContextAdapter) .ObjectContext'), tôi đang cố gắng tìm hiểu cách lấy các tên khóa chính của một thực thể –

+0

Đây là cách tiếp cận cũ, nó truy cập cơ sở dữ liệu tuy nhiên http://stackoverflow.com/questions/2958921/ thực thể-khung-4-how-to-tìm-the-primary-key/2959046 # 2959046 –

1

Bạn có thể tìm thấy giá trị khóa chính từ lớp EntityKey (http://msdn.microsoft.com/en-us/library/system.data.entitykey.aspx).

và bạn có thể tìm thấy đối tượng EntityKey từ DbContext như vậy:

ObjectContext context = ((IObjectContextAdapter)dbContext).ObjectContext; 
EntityKey key = context.ObjectStateManager.GetObjectStateEntry(model).EntityKey; 
+1

@agussyahpurta Điều này sẽ chỉ làm việc đối tượng nhà nước đối tượng quản lý có nhà nước cho các đối tượng mô hình nếu không nó sẽ sụp đổ –

1

Đây là những gì tôi đã làm để đảm bảo rằng tôi có chìa khóa. Về cơ bản nó giống như câu trả lời của @Agus Syahputra với một khác biệt quan trọng. Tôi đã thêm toàn bộ câu trả lời dưới đây.

Lưu ý: Tôi đã thử nghiệm điều này chỉ trên EF6 và tôi không chắc chắn nếu điều này làm việc với các phiên bản trước của EF.

//I'm currently inside savechanges of my dbcontext 
//if you're typing this code outside your dbcontext, replace this with your dbcontext  
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity); 
    string keyName = objectStateEntry.EntityKey.EntityKeyValues[0].Key; 
+0

này phải là câu trả lời đúng – gidanmx2

4

solution proposed by Ladislav Mrnka sẽ không hoạt động đối với các thực thể có nguồn gốc là You can't create an object set for a derived type. Bạn sẽ thấy lỗi này:

ArgumentException: Không có EntitySets được xác định cho các loại hình tổ chức quy định ... Nếu ... là một loại có nguồn gốc, sử dụng các loại cơ sở để thay thế. Tên tham số: TEntity

Đây là giải pháp của tôi tránh việc tạo ra một bộ đối tượng:

public string[] GetEntityKeyNames<TEntity>(DbContext context) 
{ 
    if (context == null) 
    { 
     throw new ArgumentNullException("context"); 
    } 
    var objectContext = ((IObjectContextAdapter)Context).ObjectContext; 
    //We must use the namespace of the context and the type name of the entity 
    string entityTypeName = context.GetType().Namespace + '.' + typeof(TEntity).Name; 
    var entityType = objectContext.MetadataWorkspace.GetItem<EntityType>(entityTypeName, DataSpace.CSpace); 
    return entityType.KeyProperties.Select(k => k.Name).ToArray(); 
}