我正在做一个遵循工作单元模式的接口。我的界面如下所示:
public interface IDataContext : IDisposable
{
void SaveChanges();
TSource Create<TSource>(TSource toCreate) where TSource : class;
TSource Update<TSource>(TSource toUpdate) where TSource : class;
bool Delete<TSource>(TSource toDelete) where TSource : class;
IQueryable<TSource> Query<TSource>();
}到目前一切尚好。现在我在我的数据层中实现它,它使用EF4作为数据提供程序。我为"Query“方法想出了这段代码,但我认为它不是很干净,我觉得有一种聪明的方法可以做到这一点,但我真的搞不懂。
public IQueryable<TSource> Query<TSource>()
{
var type = typeof(TSource);
IQueryable item = null;
if (type == typeof(Activity)) item = _entities.ActivitySet;
if (type == typeof(Company)) item = _entities.CompanySet;
if (type == typeof(Phase)) item = _entities.PhasesSet;
if (type == typeof(Project)) item = _entities.ProjectSet;
if (type == typeof(ProjectState)) item = _entities.ProjectStateSet;
if (type == typeof(ProjectType)) item = _entities.ProjectTypeSet;
if (type == typeof(User)) item = _entities.UserSet;
if (type == typeof(UserType)) item = _entities.UserTypeSet;
if (item != null) return item as IQueryable<TSource>;
throw new NotImplementedException(string.Format("Query not implemented for type {0}", type.FullName));
}我在这里看到的问题都是每次都要测试的if,尽管我可以将它们链接在一个级联的if-else中,但在我看来仍然非常糟糕。另一个问题是,我必须为每个可能添加的新实体手动添加一行,但这不是我主要关心的问题。
有人对此有什么好的建议吗?谢谢。
发布于 2010-12-28 21:47:20
如果你使用的是EF4,你可以直接调用CreateObjectSet<>。
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
namespace WindowsFormsApplication1
{
static class Program
{
[STAThread]
static void Main()
{
var context = new DataContext(new NorthwindEntities());
var list = context.Query<Customer>().ToList();
var list2 = context.Query<Customer>().ToList();
}
}
public class DataContext : IDataContext
{
private Dictionary<Type, object> _objectSets = new Dictionary<Type,object>();
private ObjectContext _entities;
public DataContext(ObjectContext objectContext)
{
this._entities = objectContext;
}
public IQueryable<T> Query<T>()
where T : class
{
Type entityType = typeof(T);
ObjectSet<T> objectSet;
if (this._objectSets.ContainsKey(entityType))
{
objectSet = this._objectSets[entityType] as ObjectSet<T>;
}
else
{
objectSet = this._entities.CreateObjectSet<T>();
this._objectSets.Add(entityType, objectSet);
}
return objectSet;
}
}
interface IDataContext
{
IQueryable<T> Query<T>() where T : class;
}
}如果您使用的是EF1,您可以调用CreateQuery<>,但您还需要找到实体集名称。
using System;
using System.Collections.Generic;
using System.Data.Metadata.Edm;
using System.Data.Objects;
using System.Linq;
namespace WindowsFormsApplication2
{
static class Program
{
[STAThread]
static void Main()
{
var context = new DataContext(new NorthwindEntities());
var list = context.Query<Customer>().ToList();
}
}
public class DataContext : IDataContext
{
private Dictionary<string, string> _entitySets;
private ObjectContext _entities;
public DataContext(ObjectContext objectContext)
{
this._entities = objectContext;
}
public IQueryable<T> Query<T>()
where T : class
{
return this._entities.CreateQuery<T>(this.GetEntitySetName<T>());
}
private string GetEntitySetName<T>()
where T : class
{
if (this._entitySets == null)
{
// create a dictionary of the Entity Type/EntitySet Name
this._entitySets = this._entities.MetadataWorkspace
.GetItems<EntityContainer>(DataSpace.CSpace)
.First()
.BaseEntitySets.OfType<EntitySet>().ToList()
.ToDictionary(d => d.ElementType.Name, d => d.Name);
}
Type entityType = typeof(T);
// lookup the entity set name based on the entityType
return this._entitySets[entityType.Name];
}
}
interface IDataContext
{
IQueryable<T> Query<T>() where T : class;
}
}发布于 2010-12-28 21:45:51
一种方法是不对所有预定义的ObjectSets使用自动生成的ObjectContext,而是调用:
public IQueryable<TSource> Query<TSource>
{
return _entities.CreateObjectSet<TSource>();
}但我不确定每次想要执行查询时创建对象集对性能有什么影响。我通常会对对象集进行一些懒惰的初始化(使用字典来存储已经创建的对象集),并在单个工作单元实例中重用它们。
https://stackoverflow.com/questions/4545938
复制相似问题