2012-01-12 30 views
3

我目前使用的是通用的存储库模式与实体框架代码首先一个存储库模式与EF代码第一时:如下LINQ的子查询中使用

public interface IRepository<TEntity> where TEntity : class 
{ 
    void Add(TEntity entity); 
    void Delete(TEntity entity); 
    TEntity GetById(int id); 
    IEnumerable<TEntity> GetAll(); 
} 

public interface IUserRepository : IRepository<User> 
{ 
    IEnumerable<User> GetAllWithSubQuery(); 
} 

public interface IBlackListRepository : IRepository<BlackList> 
{ 
} 

public interface IUserProccessedRepository : IRepository<UserProcessed> 
{ 
} 

public IEnumerable<User> GetAllWithSubQuery() 
{ 
    var result = Database.Set<User>().Where(x => x.UsersProccessed.Any()) 
            .ToList(); 

    return result; 
} 

该模型建立:

modelBuilder.Entity<UserProcessed>().HasRequired(x => x.User) 
            .WithMany(x => x.UsersProccessed) 
            .Map(x => x.MapKey("UserId")); 

的问题是,我想添加一个子查询到上面的LINQ中,所以它会做类似这样的事情:

SELECT  u.Email 
FROM  Users u INNER JOIN UsersProcessed up ON u.Id = up.UserId 
WHERE  u.Email NOT IN 
      (
       SELECT Email 
       FROM BlackList 
      ) 

但由于用户存储库是用户特定的,并且在模型中用户和BlackList之间没有建立关系,所以我不知道如何子查询BlackList。我不相信用户和黑名单表之间应该有关系,因为黑名单中的电子邮件是从第三方填充的,并且独立于用户表。

回答

1

也许我误解,但你可以在LINQ这样定义一个子查询:

IQueryable<string> blacklistedMailAddresses = 
    Database.Set<Blacklist>().Select(b => b.Email); 

var result = Database.Set<User>() 
    .Where(x => x.UsersProccessed.Any()) 
    .Where(x => !blacklistedMailAddresses.Contains(x.Email)) 
    .ToList(); 
+0

的问题是,我不能做Database.Set (),因为它的用户特定的UserRepository内。也许我需要将IQueryable传递给GetAllWithSubQuery? – Thomas 2012-01-12 16:56:21

+0

你正在做的事似乎并不适用于存储库。为什么不创建同时使用用户存储库和黑名单存储库的服务? – Steven 2012-01-12 22:13:14

+1

+1 - 如果事情要在查询中连接,他们应该在同一个存储库恕我直言 – 2012-01-14 08:48:57