根据类的实例公开属性

时间:2018-03-07 18:23:40

标签: c# entity-framework generics dbcontext

我有一个课程如下:

public class UnitofWork<T> : IDisposable where T : DbContext, new(){
    private readonly T context = new T();
    private DbRepository<TypeA> _typeA;
    private DbRepository<TypeB> _typeB;

    public DbRepository<TypeA> TypeAProp
    {
        get
        {
            return _typeA ?? (_typeA= new DbRepository<TypeA>(context as SqlContext));
        }
    }

    public DbRepository<TypeB> TypeBProp
    {
        get
        {
            return _typeB ?? (_typeB= new DbRepository<TypeB>(context as OracleContext));
        }
    }
} 

SqlContext OracleContext 都是DbContext的子类。 TypeA&amp; TypeB是EF自动生成的实体。

我在这里要完成的是说我创建了一个ClassA对象的实例..

var sqlDb = new UnitofWork<SqlContext>();

我不想为此对象实例公开属性TypeBProp。同样如果我创建如下的ClassA实例,我不想公开TypeAProp。

var oracleDb = new UnitofWork<OracleContext>();

甚至可能吗? 在此先感谢!

  • 约翰尼拉

3 个答案:

答案 0 :(得分:2)

ClassA clealry不是通用的。为了使它成为通用的,它需要被设计为正常运行无论提供什么类型作为泛型参数。你的类型没有这样做,它实际上只支持两种不同的类型,它需要根据提供的两种类型中的哪种类型而有所不同。

解决方案是有两个类,一个用于SQL版本,一个用于Oracle版本,每个类别都有适合其上下文的成员。

答案 1 :(得分:2)

似乎Oracle和SQL在您需要不同类的地方有所不同。您仍然可以从基础派生,如下所示:

public class UnitofWork<T> : IDisposable where T : DbContext, new()
{
    //Same as you had it, but without TypeAProp and TypeBProp,
    //which we will add to the subclasses below
}

public class SqlServerUnitOfWork : UnitOfWork<SqlContext>
{
    protected DbRepository<TypeA> _typeA;

    public DbRepository<TypeA> TypeAProp
    {
        get
        {
            return _typeA;
        }
    }
}

public class OracleUnitOfWork : UnitOfWork<OracleContext>
{
    protected DbRepository<TypeB> _typeB;

    public DbRepository<TypeB> TypeBProp
    {
        get
        {
            return _typeB;
        }
    }
}

用以下方式调用:

var sqlDb = new SqlServerUnitOfWork();
var a = sqlDb.TypeAProp;
var oracleDb = new OracleUnitOfWork();
var b = oracleDb.TypeBProp;

答案 2 :(得分:1)

不,它不可行。

一旦你的代码在类的括号内,它就在里面。它将公开所有属性。

解决方案可能是:

public class UnitOfWork<T, CT> : IDisposable 
        where T : DbContext, new(){
    private readonly T context = new T();

    private DbRepository<CT> _type;

    public DbRepository<CT> Repository
    {
        get
        {
            return _type ?? (_type= new DbRepository<CT>(context);
        }
    }    

} 

以下是一些用例:

var oraclePersonUoW = new UnitOfWork<OracleContext, Person>();
var oracleBookUoW = new UnitOfWork<OracleContext, Book>();
var sqlPersonUoW = new UnitOfWork<SqlContext, Person>();
var sqlBookUoW = new UnitOfWork<SqlContext, Book>();