Linq2SQL + Repository模式:如何实现类型相关的映射

时间:2011-01-06 21:34:40

标签: c# linq-to-sql orm

我实现了Repository模式以通过Linq2Sql ORM访问DB数据:

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;
}

以下是特定Repository实现的示例:

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,
                    }
         ;
    }

此处,SpecificCustomerProduct继承自CommonCustomerProduct。

提供的源代码显示了来自DB的记录如何根据实例类型映射到不同的实例。这些类有很多共同的领域,只有少数不同。

我对此代码有两个顾虑:

  1. 分配操作的一些重复;
  2. 可读性低:为了添加更多具体类,我需要制作不可读的链:

    return dbEntity => dbEntity.ProdId == iType1
                    ? new Type1
                    {
                        ... assignments
                    }
                    : 
                    {
                        dbEntity.ProdId == iType2
                        ? new Type2
                        {
                            ... assignments
                        }
                        : new Type3
                        {
                            ... assignments
                        }
                    }
    
  3. 有没有更好的方法来实现这种模式的'类型相关'映射?

1 个答案:

答案 0 :(得分:1)

你看过LINQ to SQL's Inheritance mapping了吗?它允许您使用数据库列(类型鉴别器)将不同的类映射到公共表,以确定要生成的对象类型。