I have the Repository pattern implemented to access DB data through the Linq2Sql ORM:
public abstract class RepositoryBase<T, TDb> : IRepository<T>
where T : IEntity
where TDb : class, IDbEntity, new()
{
protected RepositoryBase(IUnityContainer container)
{
_container = container;
_context = _container.Resolve<CMCoreDataClassesDataContext>();
}
public IQueryable<T> GetAll()
{
return GetTable().Select(GetConverter());
}
protected abstract Table<TDb> GetTable();
protected abstract Expression<Func<TDb, T>> GetConverter();
protected CMCoreDataClassesDataContext Context { get { return _context; } }
private readonly IUnityContainer _container;
private readonly CMCoreDataClassesDataContext _context;
}
Here is an example of particular Repository implementation:
public class CustomerProductRepository
: RepositoryBase<ICommonCustomerProduct, CMCoreDAL.DbData.CustomerProduct>
{
protected override Table<CMCoreDAL.DbData.CustomerProduct> GetTable()
{
return Context.CustomerProducts;
}
protected override Expression<Func<CMCoreDAL.DbData.CustomerProduct, ICommonCustomerProduct>> GetConverter()
{
return dbEntity => dbEntity.ProdId == (int)ProductType.ProductTypeEnum.CommonProduct
? new CommonCustomerProduct
{
UnityContainer = UnityContainer,
InstanceId = dbEntity.InstanceId,
CustomerId = dbEntity.CustomerID,
StatusCode = dbEntity.StatusCode,
DeviceLicenses = dbEntity.DeviceLicenses,
ServerLicenses = dbEntity.ServerLicenses,
}
: new SpecificCustomerProduct()
{
UnityContainer = UnityContainer,
InstanceId = dbEntity.InstanceId,
CustomerId = dbEntity.CustomerID,
StatusCode = dbEntity.StatusCode,
UserLicenses = dbEntity.DeviceLicenses,
}
;
}
Here SpecificCustomerProduct is inherited from CommonCustomerProduct.
Presented source code shows how records from DB are mapped to different instances according to instance type. There are a lot of common fields for these classes and only few of them are different.
I have 2 concerns for this code:
- Some duplications of assignment operations;
Low readability: in order to add few more concrete classes I need to make unreadable chain:
return dbEntity => dbEntity.ProdId == iType1 ? new Type1 { ... assignments } : { dbEntity.ProdId == iType2 ? new Type2 { ... assignments } 开发者_C百科 : new Type3 { ... assignments } }
Is there any better way to implement 'type-related' mapping with such pattern?
Have you looked at LINQ to SQL's Inheritance mapping? It allows you to map different classes to a common table, using a database column (type discriminator) to determine which type of object to generate.
精彩评论