[英]Any tips on avoiding code Duplication on this abstraction?
So I'm building an App using the Entity Framework on top of SQL Compact Edition. 所以我正在使用SQL Compact Edition上的Entity Framework构建一个App。 I didn't like the idea of using the Entites as my business objects so I've been building a layer (I've called it ObjectModel layer, prob not the best terminology) in-between that will take my plain objects, use them to populate and save the entities.
我不喜欢使用Entites作为我的业务对象的想法,所以我一直在构建一个层(我称之为ObjectModel层,不是最好的术语)介于两者之间,它将采用我的普通对象,使用它们填充和保存实体。 And also vice versa - take entites, populate the POCOs for use as business object
反之亦然 - 采取行动,填充POCO作为业务对象
Let's say I have a POCO object called Customer, 假设我有一个名为Customer的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
}
And I want to populate this using my ObjectModel layer. 我想用我的ObjectModel层填充它。 I currently do this...
我目前这样做......
OM_Customer<ICustomer,Entity.Customer> customerLayer = new OM_Agent<ICustomer,Entity.Customer>();
ICustomer businessObject = customerLayer.GetById(new Guid("4a75d5a5-6f5a-464f-b4b3-e7807806f1a9"));
The OM_Customer class inherits from ObjectModelBase, which is below.. 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);
}
}
}
The problem here lies with the GetById method. 这里的问题在于GetById方法。 The Save method can be used by subclasses fine as all Entity Framework Object Contexts have the AddObject() method.
子类可以使用Save方法,因为所有实体框架对象上下文都有AddObject()方法。
However, I wish to have a generic getById method, as all my entities will have a property called id (in the db as well, being the primary key).The problem is that the linq here... 但是,我希望有一个通用的getById方法,因为我的所有实体都有一个名为id的属性(在db中也是主键)。问题是这里的linq ...
ModelClass result = (ModelClass)((object)(from c in db.CustomerSet where c.id == id select c).First());
is specific to db.CustomerSet . 特定于db.CustomerSet 。 I wish to have this abstract class provide the generic CRUD/Paging/'Collection Retrieval' for all my entities, but without the repetitive keystrokes, however, this simple GetById method has driven me to ask for help.
我希望这个抽象类为我的所有实体提供通用的CRUD / Paging /'Collection Retrieval',但是没有重复的击键,这个简单的GetById方法促使我寻求帮助。
Current ideas : 目前的想法:
Would appreciate any adivce as to how the SO community would go about solving the above. 非常感谢SO社区如何解决上述问题。
First, I would start by questioning why you feel that using EF entities as you business entities would necessarily be a bad thing? 首先,我将首先质疑为什么你觉得使用EF实体,因为你的业务实体一定是坏事? I've done so on a number of projects and I have yet to run into any serious issues that I can't overcome.
我已经完成了许多项目,但我还没有遇到任何我无法克服的严重问题。
Having said that, if you really feel you have a strong reason to separate the two, here's one option. 话虽如此,如果你真的觉得你有充分的理由将两者分开,这里有一个选择。
You can use a delegate to inject the specific entity set object to query and another for the selector for the key - it could allows derivatives to only specify their storage semantics. 您可以使用委托将特定实体集对象注入查询,将另一个委托注入密钥的选择器 - 它可以允许衍生工具仅指定其存储语义。 So your code would look like:
所以你的代码看起来像:
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)); }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.