好吧,您已经走在正确的轨道上,只需实现您想要的内容即可:)
1.您将表达式传递到您的 find 方法中,因此只需在 Where 子句中使用该表达式
2.你只需要从你的 DbContext 中获取正确的 DbSet 来查询,DbContext 有一个方法来获取给定类型的 DbContext,使用它,你可以像这样查询
public IQueryable<T> Find<T>(Expression<Func<T, bool>> query) where T : IMyDomainEntity
{
var dbSet = context.Set<T>();
return dbSet.Where(query);
}
3.如果您的域对象不是 EF 映射到数据库的对象,您需要根据 DbContext 类中的数据库中的内容自定义映射(不需要自动映射器),所以您会有这样的东西在您的 DbContext 类中
public class MyContext : DbContext
{
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.Map(a => a.ToTable("DB_USERS"))
.Property(a => a.Email).HasColumnName("MAIL");
base.OnModelCreating(modelBuilder);
}
}
要从数据库中的表 DB_USERS 映射到用户类,字段具有不同的名称等,这里有一篇文章
http://www.codeproject.com/Articles/165720/Using-the-Code-First-Model-Configuration-Classes
如果您不想/不能更改 DbContext 类,也可以使用属性将属性映射到正确的表列
http://msdn.microsoft.com/en-us/data/gg193958
或者您可以将一组不同的实体映射到您的数据库并使用自动映射器将它们转换为您的域对象,但您不会丢失。4 bellos,因为您需要具体化查询以将其自动映射到您的域模型。
4.不需要做任何特别的事情,EF会照顾
更新:没有访问 DbContext 的解决方案(不是完全通用的版本,但有效)
这个想法是为每个域类创建存储库的映射部分,以便正确绑定所有内容。继续User
域模型和DBUser
表模型:
public class User : IDomainModelEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class DBUser
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int USER_ID { get; set; }
[Required]
[MaxLength(150)]
public string USER_NAME { get; set; }
[Required]
[MaxLength(260)]
public string USER_MAIL { get; set; }
}
然后,您将拥有一个抽象存储库和一个具体的存储库,每个域类实现基本的 GetAll 查询映射:
public abstract class Repository<T> where T : IDomainModelEntity
{
protected readonly DbContext _context;
public Repository(DbContext context)
{
_context = context;
}
public abstract IQueryable<T> GetAll();
public IQueryable<T> Find(Expression<Func<T, bool>> predicate)
{
return GetAll().Where(predicate);
}
}
public class UserRepository : Repository<User>
{
public UserRepository(DbContext context)
: base(context)
{
}
public override IQueryable<User> GetAll()
{
return _context.Set<DBUser>()
.Select(u => new User
{
Id = u.USER_ID,
Name = u.USER_NAME,
Email = u.USER_MAIL
});
}
}
现在要使用它,您只需调用 find 或 get all on the repository ...
using (var context = new CompanyDbContext())
{
var repo = new UserRepository(context);
var list = repo.Find(a=>a.Id >= 2).ToList();
list.ForEach(a => Console.WriteLine("Id: {0}, Name {1}, email {2}", a.Id, a.Name, a.Email));
}
它不是完全通用的,因为您需要为需要使用的每个域类传递一个存储库,但这可能是一个可以接受的折衷方案
希望这可以帮助