2012-09-22 14 views
2

在實體框架中實現泛型持久化方法的最佳解決方案是什麼?實體框架中的一般持久化方法 - 插入或更新(如果存在)實體

例如有一個公司實體:

public class Company 
{ 
    public Company() 
    { 
     Id = Guid.NewGuid(); 
    } 

    public Guid Id { get; set; } 

    public string Name { get; set; } 
} 

Id屬性可以之前實體被存儲到數據庫中來生成。

所以任務是實現持久方法:

public class Repository 
{ 
    private DbSet<Company> _dbSet; 

    public void Persist(Company company) 
    { 
     // How to implement body here to Add entity if it doesn't exists yet 
     // or Modify it in opposit case? 
     // In terms of database entity record is required to be inserted or updated. 
    } 
} 

謝謝!

回答

4

在你的例子,如果Company實例是新的或已被以前從數據庫加載,你必須查詢數據庫,你可以不承認:

public void Persist(Company company) 
{ 
    var companyInDb = _dbSet.SingleOrDefault(c => c.Id == company.Id); 
    if (companyInDb != null) 
    { 
     _context.Entry(companyInDb).CurrentValues.SetValues(company); 
    } 
    else 
    { 
     _dbSet.Add(company); 
    } 
    _context.SaveChanges(); 
} 

正如你所看到的,你需要一個參考您的存儲庫中的上下文_context

另一種方法是可能的,如果你標誌着公司新的或從數據庫加載,例如有一個特殊的構造:

public class Company 
{ 
    public Company() 
    { 
    } 

    public Company(bool isNew) 
    { 
     Id = Guid.NewGuid(); 
     _isNew = isNew; 
    } 

    public Guid Id { get; set; } 
    public string Name { get; set; } 

    private bool _isNew; 
    public IsNew { get { return _isNew; } } 
} 

Persist方法就不會再需要加載原:

public void Persist(Company company) 
{ 
    if (!company.IsNew) 
    { 
     _context.Entry(company).State = EntityState.Modified; 
    } 
    else 
    { 
     _dbSet.Add(company); 
    } 
    _context.SaveChanges(); 
} 

請注意,所有這些僅更新公司的標量屬性,而不是關係。

+0

謝謝你的回答! – Jekas

+0

@Slauma:對於第二個選項,如果對象不是來自數據庫,而是來自另一個來源與數據庫同步,那麼又如何不知道對象是否是新的? –

+0

@JoshuaFrank:然後第二個選項不能使用,只有第一個選項。如果您想避免查詢數據庫,我認爲您唯一的選擇是編寫一個存儲過程,以決定是否需要插入或更新對象。我肯定會從選項1開始,只有在遇到嚴重的性能問題時才考慮使用存儲過程。 – Slauma