2013-10-03 48 views
2

我想將我的UserCompany對象插入到數據庫中。如將元素傳遞給該函數,將其帶入「插入右側表格」。自動/智能插入「本身」對象

通常在實體(如LINQ到XML)我不喜歡出頭:

db.Company.UsersCompany.Add(UserCompany); 
db.SubmitChanges(); 

但這裏的問題是,我需要在使用前.Add()指定表UsersCompanyCompany。 我想(因爲我想爲每種類型的對象/表插入一個函數)擺脫這一點。如具有:

UserCompany.InsertMySelf(); 

db.SmartAdd(UserCompany); 

,並知道如何自動插入表格,在哪裏以及如何。

可以做到這一點嗎?有沒有什麼策略?

+1

您的上下文中的存儲庫模式?在該方法內基於對象類型切換? –

+0

你能舉一個例子嗎? – markzzz

+1

是的,給我幾分鐘鍵入一些代碼。 –

回答

1

在你Controller定義存儲庫爲自己沿着這些路線:

public class CompanyController : ApiController 
{ 
    private readonly CompanyRepository _companyRepository; 

    public CompanyController() 
    { 
     _companyRepository= new CompanyRepository(User); 
    } 

    [HttpPost] 
    public Company PostCompany(Company comp) 
    { 
     _companyRepository.SmartAdd(comp); 
    } 
} 

定義存儲庫的定義:

public class CompanyRepository : EFContextProvider<CompanyContext> 
{ 
    // Fields which can be used for security within the repository. 
    public IPrincipal User { get; private set; } 
    public string UserName { get; set; } 

    public CompanyRepository (IPrincipal user) 
    { 
     User = user; 
     UserName = user.Identity.Name; 
    } 

    public DbQuery<Object> SmartAdd(Object obj) 
    { 
     switch (obj.GetType) 
     { 
      case "": // TODO... 
       Context.Company.UsersCompany.Add(UserCompany); 
       break; 

      default: 
       break; 
     } 
    } 

有將有一些適應適合自己的需要,但這是一般的想法。

雖然在交換機內可能會有很多情況,但我認爲你會做對象驗證和其他事情,所以你也可以在這裏輕鬆地做到這一點。

相關鏈接:

+0

這是我想避免的:'select case'。如果我有25張桌子怎麼辦?一個25開關的開關?呃...不一致...... – markzzz

+0

這是怎麼不一致的?這一切都在一個地方,對於使用實際API的人員來說,這當然更易於管理。如果你願意,你可以把它分解得更多並且不斷抽象,但我認爲這不會對你的事業有所幫助。否則,請爲數據庫中的每個對象定義一個類型,然後根據您試圖保存的對象針對每個表的模式運行SQL,以減少性能和空間。 –

2

您可以使用泛型解決這個問題:

Public Sub AddEntities(Of TEntity)(entities As IEnumerable(Of TEntity)) 
    For Each ent In entities 
     _db.Set(Of TEntity).Add(ent) 
    Next 
    _db.SaveChanges() 
End Sub 

對不起,使用VB ... 在C#:

public void AddEntities<TEntity>(IEnumerable<TEntity> entities) 
    { 
    foreach(ent in entities) 
    { 
     _db.Set<TEntity>.Add(ent); 
    } 
    _db.SaveChanges(); 
    } 
0

您需要查看通用存儲庫。該模式通過一個基類提供所有CRUD。然後,您可以從該類繼承來實現自定義的倉庫,它有必要

public class RepositoryBase<T> : IRepository<T> where T : ModelBase 
{ 
    private readonly IUnitOfWork _UnitOfWork; 
    //https://stackoverflow.com/questions/4442828/entity-framework-4-ctp-4-ctp-5-generic-repository-pattern-and-unit-testable/4458250#4458250 


    protected MyContext Context { get { return _UnitOfWork.Context; } } 

    public RepositoryBase(IUnitOfWork unitOfWork) 
    { 
     _UnitOfWork = unitOfWork; 
    } 

    public virtual T InsertOrUpdate(T e) 
    { 
     DbSet<T> dbSet = Context.Set<T>(); 

     DbEntityEntry<T> entry; 
     if (e.GetType().BaseType != null && e.GetType().Namespace == "System.Data.Entity.DynamicProxies") 
     { 
      //The entity being added is already a proxy type that supports lazy loading 
      //just get the context entry 
      entry = Context.Entry(e); 
     } 
     else 
     { 
      //The entity being added has been created using the "new" operator. 
      //Generate a proxy type to support lazy loading and attach it 
      T instance = dbSet.Create(); 
      instance.ID = e.ID; 
      entry = Context.Entry(instance); 
      dbSet.Attach(instance); 

      //and set it's values to those of the entity 
      entry.CurrentValues.SetValues(e); 
      e = instance; 
     } 

     entry.State = e.ID == default(int) ? 
           EntityState.Added : 
           EntityState.Modified; 

     return e; 
    } 

    public virtual IQueryable<T> All 
    { 
     get 
     { 
      return Context.Set<T>(); 
     } 
    } 

    public virtual IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties) 
    { 
     IQueryable<T> query = All; 
     foreach (var includeProperty in includeProperties) 
     { 
      query = query.Include(includeProperty); 
     } 
     return query; 
    } 

    public virtual T Find(int id) 
    { 
     T e = Context.Set<T>().Find(id); 
     if (e == null) 
      return null; 

     return e; 
    } 

    public virtual void Delete(int id) 
    { 
     var e = Context.Set<T>().Find(id); 

     if (e != null) 
      Context.Set<T>().Remove(e); 

    } 
} 

public abstract class ModelBase 
{ 
    public int ID { get; set; } 
} 

參考文獻:

The repository and unit of work patterns

John Papa's original source

How to ensure proxies are created when using the repository pattern

Generic Repository Pattern