我有一个客户端 - 服务器架构,其中服务器使用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; }
}
当然,实际的实体不会被共享。
程序的不同部分只需要部分数据。例如。一部分可以使用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
一起使用。
我想在客户端重用服务器的某些部分。当然,客户端没有DbSet
,但是通过服务器的WCF服务检索其数据。因此,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
。它不能直接转换,因为DbSet
没有实现接口,尽管它包含所有成员。我尝试了一些不同的方法,但都没有真正奏效:
创建DbSet
的子类,实现所需的接口( - &gt;类适配器)。
这不起作用,因为IDbSet
没有任何公共或受保护的构造函数。因此,适配器类无效。
我没有使用适配器类,而是尝试使用适配器接口,该接口派生自public ICustomDbSet<SharedType> MyEntities{ get; set; }
IEntityCache<SharedType> IEntityProvider<SharedType>.Elements { get { return MyEntities; } }
和必要的接口:
ICustomDbSet
这不起作用,因为EntityFramework未设置IEntityCache
。可能因为它设置的值不是{{1}}。
在写这个问题时,我发现了一个非常好的解决方案(我将作为答案发布)。那么为什么我发布这个问题呢?首先,我想知道,如果有任何其他方法似乎更合理,如果我的解决方案有一些缺点。其次,解决方案可能会帮助其他人。第三,写这个问题需要一段时间,把它扔掉会很遗憾:)
答案 0 :(得分:0)
我的解决方案是类适配器方法的后续步骤:使用对象适配器:
public class DbSetAdapter<TEntity> : IEntityCache<TEntity> where TEntity : class
{
DbSet<TEntity> dbSet;
public DbSetAdapter(DbSet<TEntity> dbSet)
{
this.dbSet = dbSet;
}
public ObservableCollection<TEntity> Local
{
get { return dbSet.Local; }
}
public TEntity Add(TEntity entity)
{
return dbSet.Add(entity);
}
public TEntity Remove(TEntity entity)
{
return dbSet.Remove(entity);
}
public IEnumerator<TEntity> GetEnumerator()
{
return ((IEnumerable<TEntity>)dbSet).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)dbSet).GetEnumerator();
}
public Type ElementType
{
get { return ((IQueryable<TEntity>)dbSet).ElementType; }
}
public Expression Expression
{
get { return ((IQueryable<TEntity>)dbSet).Expression; }
}
public IQueryProvider Provider
{
get { return ((IQueryable<TEntity>)dbSet).Provider; }
}
}
我在DbContext
中使用了此适配器,如下所示:
DbSetAdapter<SharedType> entityAdapter;
...
public DbSet<SharedType> MyEntities{ get; set; }
IEntityCache<SharedType> IEntityProvider<SharedType>.Elements {
get
{
if (entityAdapter == null)
entityAdapter = new DbSetAdapter<SharedType>(MyEntities);
return entityAdapter;
}
}
这样,IEntityCache
可以以从服务而不是数据库中检索数据的方式实现。此外,该计划的子部分不必关心其数据来自何处。