2009-07-06 44 views
3

因此,我正在使用SQL精简版上的实体框架构建应用程序。我不喜欢使用Entites作为我的业务对象的想法,因此我一直在构建一个图层(我称它为ObjectModel图层,不是最好的术语),它会占用我的普通对象,使用它们填充和保存实体。而且反之亦然 - 采取的entites,填充波苏斯用作业务对象在这个抽象上避免代码复制的任何提示?


比方说,我有一个名为客户一个POCO对象,

public class Customer:ICustomer 
    { 


     #region ICustomer Members 

     public System.Guid id {get;set;} 


     public string Forename {get;set;} 


     public string Surname { get; set; } 


     #endregion 
    } 

我要填充这个用我ObjectModel层。我目前做到这一点...

OM_Customer<ICustomer,Entity.Customer> customerLayer = new OM_Agent<ICustomer,Entity.Customer>(); 

ICustomer businessObject = customerLayer.GetById(new Guid("4a75d5a5-6f5a-464f-b4b3-e7807806f1a9")); 

的OM_Customer类从ObjectModelBase,低于继承..

public abstract class ObjectModelBase<BllClass, EntityClass> 
{ 
    public DataStoreEntities1 db; 

    public EntityClass _dataObject; 

    public string setName; 


    #region POCO-ORM Mapping Functions 
    public EntityClass MapBLLToEntity(BllClass bllObject) 
    { 
     Mapper.CreateMap<BllClass, EntityClass>(); 
     return Mapper.Map<BllClass, EntityClass>(bllObject); 
    } 

    public BllClass MapEntityToBLL(EntityClass entityObject) 
    { 
     Mapper.CreateMap<EntityClass, BllClass>(); 
     return Mapper.Map<EntityClass, BllClass>(entityObject); 
    } 
    #endregion 

    public void Save(BllClass toAdd) 
    { 
     _dataObject = MapBLLToEntity(toAdd); 

     using (db = new DataStoreEntities1()) 
     { 
      db.AddObject(setName, _dataObject); 
      db.SaveChanges(); 
     } 
    } 

    public BllClass GetById(Guid id) 
    { 
     using (db = new DataStoreEntities1()) 
     { 
      EntityClass result = (EntityClass)((object)(from c in db.CustomerSet where c.id == id select c).First()); 
      return MapEntityToBLL(result); 
     } 

    } 

} 

这里的问题在于与GetById方法。由于所有实体框架对象上下文都有AddObject()方法,所以子类可以使用Save方法。

不过,我希望有一个通用的方法getById,因为我所有的实体将有一个属性叫做id(在DB以及,作为主键)。问题是,这里的LINQ ...

ModelClass result = (ModelClass)((object)(from c in db.CustomerSet where c.id == id select c).First()); 

特定于db.CustomerSet。我希望这个抽象类为我的所有实体提供通用的CRUD/Paging /'Collection Retrieval',但是,如果没有重复的按键操作,这个简单的GetById方法已经促使我寻求帮助。

当前的想法:

  • 由id使用实体SQL我GET在那里我不得不在构建查询字符串更多的控制。
  • 废除实体框架和linq,因为它可能太耗费时间来完全抽象。

希望有任何关于SO社区如何解决上述问题的建议。

+0

您正在构建一个Web或Windows应用程序吗? – 2009-07-07 00:00:59

+0

这是一个Windows应用程序,但它可以很容易地成为一个Web应用程序,相关性的代码? – RekrowYnapmoc 2009-07-07 15:35:25

回答

4

首先,我将首先质疑为什么你认为使用EF实体作为商业实体必然是件坏事?我在很多项目上都这样做了,但我还没有遇到任何我无法克服的严重问题。说了这么多,如果你真的觉得你有强烈的理由来分开这两个,这里有一个选择。

您可以使用委托将特定的实体集对象注入到查询中,并使用另一个用于键的选择器 - 它可以允许派生类仅指定其存储语义。因此,您的代码如下所示:

public abstract class ObjectModelBase<BllClass, EntityClass> 
{ 
    // ... same basic code here... 

    // supplied by your derivatives... 
    protected abstract Func<IQueryable<EntityClass>> GetEntitySet { get; }; 
    protected abstract Func<Guid,Func<EntityClass,bool>> KeySelector { get; } 

    public BllClass GetById(Guid id) 
    { 
     using (db = new DataStoreEntities1()) 
     { 
      EntityClass result = (EntityClass)((object) 
       GetEntitySet() 
        .Where(KeySelector(id)) 
        .First(); 
      return MapEntityToBLL(result); 
     } 
    } 
} 

public class OM_Customer : ObjectModelBase<ICustomer,Entity.Customer> 
{ 
    protected abstract Func<IQueryable<Entity.Customer>> GetEntitySet 
    { 
     get { return db.CustomerSet; } 
    } 

    protected abstract Func<Guid,Func<Entity.Customer,bool>> KeySelector 
    { 
     get { return (g => (e => e.Id == g)); } 
    } 
}