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));
}
}
}
SqlContext和OracleContext都是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