介绍
我有一个客户端-服务器架构,其中服务器使用 Entity Framework 5.0 将其数据存储在不同的数据库中。因此,它有不同的DbContext
类别。但是,它们之间共享一些实体类型。所以我们可以有:
public class MyFirstDataAccess : DbContext
{
//constructor omitted
public DbSet<SharedType> MyEntities { get; set; }
public DbSet<OtherType> MyOtherEntities { get; set; }
}
public class MySecondDataAccess : DbContext
{
public DbSet<SharedType> MyEntitiesWithSharedType { get; set; }
}
当然,实际的实体是不共享的。
问题
程序的不同部分只需要部分数据。例如,一部分可以使用 Type 的实体SharedType
。所以我创建了一个提供数据的通用接口:
public interface IEntityProvider<TEntity> where TEntity : class
{
DbSet<TEntity> Elements { get; set; }
void Dispose();
int SaveChanges();
}
DbContext
在我添加的属性中实现接口Elements
,它将替换例如MyEntitiesWithSharedType
属性:
DbSet<SharedType> IEntityProvider<SharedType>.Elements { get; set; }
这实际上有效。DbContext
只要提供所需的数据,程序的不同部分现在都可以使用。
我想在客户端重用服务器的某些部分。当然,客户端没有DbContext
,而是通过 WCF 服务从服务器检索其数据。因此,DbSet
不能在IEntityProvider
接口中使用,因为该接口必须与客户端共享。所以我创建了另一个接口,其中包含DbSet's
我需要的成员:
public interface IEntityCache<TEntity> : IEnumerable<TEntity>, IQueryable<TEntity>
{
ObservableCollection<TEntity> Local { get; }
TEntity Add(TEntity entity);
TEntity Remove(TEntity entity);
}
问题是如何DbSet
获得IEntityCache
. 它不能直接转换,因为DbSet
它没有实现接口,尽管它包含了它的所有成员。我尝试了一些不同的方法,但都没有真正奏效:
尝试 1
创建 的子类DbSet
,它实现所需的接口(--> 类适配器)。
这不起作用,因为DbSet
没有任何公共或受保护的构造函数。因此,适配器类无效。
尝试 2
我没有使用适配器类,而是尝试使用适配器接口,它派生自IDbSet
必要的接口:
public ICustomDbSet<SharedType> MyEntities{ get; set; }
IEntityCache<SharedType> IEntityProvider<SharedType>.Elements { get { return MyEntities; } }
这不起作用,因为 EntityFramework 没有设置ICustomDbSet
. 可能是因为它设置的值是 no IEntityCache
。
解决方案
在写这个问题时,我找到了一个很好的解决方案(我将作为答案发布)。那么,为什么我要发布这个问题呢?首先,我想知道,是否有任何其他看起来更合理的方法,以及我的解决方案是否有一些缺点。其次,该解决方案可能对其他人有所帮助。第三,写这个问题花了一段时间,扔掉它会很可惜:)