C# 基于类的实例公开属性

C# 基于类的实例公开属性,c#,entity-framework,generics,dbcontext,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

我的课程如下:

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));
        }
    }
} 
公共类UnitofWork:IDisposable,其中T:DbContext,new(){ private readonly T context=new T(); 私有数据库存储库_typeA; 私有数据库存储库_typeB; 公共数据库存储库类型APROP { 得到 { 返回_typeA??(_typeA=newdbrepository(上下文为SqlContext)); } } 公共数据库存储库类型BPROP { 得到 { 返回_typeB??(_typeB=newdbrepository(上下文为OracleContext)); } } } SqlContextOracleContext都是DbContext的子类。 类型A和类型B是EF自动生成的实体

我想在这里完成的是,假设我创建了一个ClassA对象的实例

var sqlDb = new UnitofWork<SqlContext>();
var sqlDb=newunitofwork();
我不想公开此对象实例的属性TypeBProp。同样,如果我像下面那样创建ClassA实例,我不想公开TypeAProp

var oracleDb = new UnitofWork<OracleContext>();
var oracleDb=newunitofwork();
这有可能吗? 提前谢谢

  • 约翰尼
  • 不,这不可行

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

    解决办法可能是:

    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);
            }
        }    
    
    } 
    
    公共类UnitOfWork:IDisposable
    其中T:DbContext,new(){
    private readonly T context=new T();
    私有数据库存储库_类型;
    公共数据库存储库
    {
    得到
    {
    返回类型??(\u类型=新数据库存储库(上下文);
    }
    }    
    } 
    
    以下是一些用例:

    var oraclePersonUoW = new UnitOfWork<OracleContext, Person>();
    var oracleBookUoW = new UnitOfWork<OracleContext, Book>();
    var sqlPersonUoW = new UnitOfWork<SqlContext, Person>();
    var sqlBookUoW = new UnitOfWork<SqlContext, Book>();
    
    var oraclepersonow=newunitofwork();
    var oracleBookUoW=newunitofwork();
    var sqlpersonow=newunitofwork();
    var sqlBookUoW=newunitofwork();
    不,这不可行

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

    解决办法可能是:

    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);
            }
        }    
    
    } 
    
    公共类UnitOfWork:IDisposable
    其中T:DbContext,new(){
    private readonly T context=new T();
    私有数据库存储库_类型;
    公共数据库存储库
    {
    得到
    {
    返回类型??(\u类型=新数据库存储库(上下文);
    }
    }    
    } 
    
    以下是一些用例:

    var oraclePersonUoW = new UnitOfWork<OracleContext, Person>();
    var oracleBookUoW = new UnitOfWork<OracleContext, Book>();
    var sqlPersonUoW = new UnitOfWork<SqlContext, Person>();
    var sqlBookUoW = new UnitOfWork<SqlContext, Book>();
    
    var oraclepersonow=newunitofwork();
    var oracleBookUoW=newunitofwork();
    var sqlpersonow=newunitofwork();
    var sqlBookUoW=newunitofwork();
    
    ClassA
    clealry不是泛型的。要使其成为泛型,无论泛型参数提供的是什么类型,都需要对其进行设计,以使其正常工作。您的类型不会这样做,它实际上只支持两种不同的类型,并且它需要根据两种pro类型中的哪一种类型来实现不同的功能录像


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

    ClassA
    clealry不是泛型的。要使其成为泛型,无论作为泛型argu提供的是什么类型,都需要对其进行设计,以便正常运行您的类型不支持这一点,它实际上只支持两种不同的类型,并且它需要根据提供的两种类型中的哪一种来执行不同的功能


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

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

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

    如果你用一些有意义的东西来替换
    T
    ClassA
    ClassB
    TypeA
    、和
    TypeB
    ,可能会有点帮助。这会使它们之间的关系变得不清楚,甚至可能暗示一种不存在的关系。这只是增加了一个认知负荷水平(无论如何,对我来说)@ScottHannen我将尝试更具描述性-将编辑帖子。你应该只放在所有派生类通用的父类/基类上。你不能有一个类,其中某些类实例公开属性,而其他实例不公开属性。这是不可能的。你可以将属性移动到更多派生类型。这听起来像是XY问题。这里有这不应该成为您尝试这样做的理由。为什么这两个类不能是具有各自属性的两个不同类?很可能您试图避免做的事情就是您应该做的事情。@ScottHannen基本上这些类是工作单元/repo实现-但它们不是使用一个数据连接,而是2个独立的数据库(一个用于SQL db,一个用于oracle)-因此,当我开始编写存储库时,它可以完美地处理一个数据上下文,但当我开始添加另一个数据上下文时,我认为我可以使repo足够通用,以处理两个上下文-它可以很好地工作,只需公开所有属性。你是对的,这听起来确实像XY问题-但我很想知道。这可能会有所帮助如果你把
    T
    ClassA
    ClassB
    TypeA
    ,和
    TypeB
    替换成有意义的东西。这会使它们之间的关系变得不清楚,甚至可能暗示一种不存在的关系。这只会增加认知负荷的水平(无论如何,对我来说)@ScottHannen我将尝试更具描述性-将编辑帖子。你应该只放在所有派生类通用的父类/基类上。你不能有一个类,其中某些类实例公开属性,而其他实例不公开属性。这是不可能的。你可以将属性移动到更多派生类型。这听起来像是XY问题。这里有不应该成为你要做的事情的理由。为什么这不能是两个不同的c