2012-04-28 86 views
0

我想寫一些東西,我可以傳入一個類(其中將包括新數據,包括主鍵值),並使用實體框架,使用主鍵檢索實體。所以,我有一個類,包括主鍵值,但我不一定知道主鍵(但實體框架)。通用實體框架更新器

(我以後還需要那麼一般更新實體,但是這是一個單獨的問題)

有一個簡單的方法在LINQ做到這一點?

回答

0

據我所知,你有一個對象沒有被上下文跟蹤,你想用EF來查詢數據庫中的等價實體。 (然後您想用對象的值更新數據庫,但這將是一個單獨的問題。)

如果知道主鍵值,可以使用Find方法從數據庫中獲取實體。棘手的問題是以通用的方式獲取主鍵值。這是我們希望在EF的未來版本中變得更容易,但現在我已經制作了一些擴展方法來提供幫助。

首先,讓我們得到給定類型的主鍵名稱。這是棘手的問題。它需要下降到ObjectContext中,並使用MetadataWorkspace:

public static IEnumerable<string> PrimayKeysFor(
     this DbContext context, 
     object entity) 
    { 
     Contract.Requires(context != null); 
     Contract.Requires(entity != null); 

     return context.PrimayKeysFor(entity.GetType()); 
    } 

    public static IEnumerable<string> PrimayKeysFor(
     this DbContext context, 
     Type entityType) 
    { 
     Contract.Requires(context != null); 
     Contract.Requires(entityType != null); 

     var metadataWorkspace = 
      ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace; 
     var objectItemCollection = 
      (ObjectItemCollection)metadataWorkspace.GetItemCollection(DataSpace.OSpace); 
     var ospaceTypes = metadataWorkspace.GetItems<EntityType>(DataSpace.OSpace); 

     var ospaceType = ospaceTypes 
      .FirstOrDefault(t => objectItemCollection.GetClrType(t) == entityType); 

     if (ospaceType == null) 
     { 
      throw new ArgumentException(
       string.Format(
        "The type '{0}' is not mapped as an entity type.", 
        entityType.Name), 
       "entityType"); 
     } 

     return ospaceType.KeyMembers.Select(k => k.Name); 
    } 
} 

現在,我們可以添加一個擴展方法,它利用這點來獲取給定的實體鍵值(它沒有被跟蹤):

public static object[] PrimayKeyValuesFor(this DbContext context, object entity) 
    { 
     Contract.Requires(context != null); 
     Contract.Requires(entity != null); 

     var entry = context.Entry(entity); 
     return context.PrimayKeysFor(entity) 
      .Select(k => entry.Property(k).CurrentValue) 
      .ToArray(); 
    } 

一旦我們有了它,使用Find可以非常容易地在數據庫中獲取與給定對象相對應的實體,而無需瞭解對象的任何信息。例如:

var databaseOrderLine = 
    context.Set<OrderLine>().Find(context.PrimayKeyValuesFor(orderLine)); 
0

您可以使用一個通用的ContextHelper:

public class ContextHelper<T> : IContextHelper<T> 
{ 
    //Instantiate your own EntityFrameWork DB context here, 
    //Ive called the my EntityFramework Namespace 'EF' and the context is  named 'Reporting' 
    private EF.DataContext DbContext = new EF.DataContext(); 
    public bool Insert<T>(T row) where T : class 
    { 
     try 
     { 
      DbContext.Set<T>().Add(row); 
      DbContext.SaveChanges(); 
      return true; 
     } 
     catch(Exception ex) 
     { 
      return false; 
     } 
    } 
    public bool Update<T>(T row) where T : class 
    { 
     try 
     { 
      DbContext.Set<T>().AddOrUpdate(row); 
      DbContext.SaveChanges(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    } 
    public bool Delete<T>(T row) where T : class 
    { 
     return Update(row); //Pass an entity with IsActive = false and call update method 
    } 
    public bool AddRows<T>(T[] rows) where T : class 
    { 
     try 
     { 
      DbContext.Set<T>().AddOrUpdate(rows); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    } 
} 

,並使用該稱呼它:

public void NewEmailRecipient(EF.EmailRecipient recipient) 
     { 
      // logic operation here 

      EntityToDB(recipient); 
     } 
     public void NewReportRecipient(EF.ReportRecipient recipient) 
     { 
      // logic operation here 

      EntityToDB(recipient); 
     } 
     public void UpdateEmailRecipient(EF.EmailRecipient recipient) 
     { 
      // logic operation here 

      UpdateEntity(recipient); 
     } 

     public void UpdateReportRecipient(EF.ReportRecipient recipient) 
     { 
      // logic operation here 

      UpdateEntity(recipient); 
     } 
     // call generic methods to update DB 
     private void EntityToDB<T>(T entity) where T : class 
     { 
      var context = new ContextHelper<T>(); 
      context.Insert(entity); 
     } 

     private void UpdateEntity<T>(T entity) where T : class 
     { 
      var context = new ContextHelper<T>(); 
      context.Update(entity); 
     } 

我已經張貼在這裏演示解決方案

https://github.com/andyf1ynn/EntityFramwork-Generic-Type-DAL