2012-06-18 26 views
0

我有一个表称为TPM_TASKS包含所有任务的所有任务,以及一个表中调用TPM_USER其中包含的所有用户。然后,我有一个名为TPM_USERTASKS表,包含UserIdTaskId存储一个任务给一个用户分配。需要EF/LINQ查询以获得分配给某个用户

我试图选择分配到给定TPM_USER实体的所有任务。到目前为止,我已经试过:

TPM_USER user = UserManager.GetUser(context, UserId); //Lookup the user in the DB 
var tasks = (from t in context.TPM_TASK.Include("TPM_USER") 
      where t.TPM_USER.Contains<TPM_USER>(user) 
      select t); 

然而,当我试图重复这个我得到的运行时异常:

无法创建类型的常量值“Entity.TPM_USER”。在此上下文中仅支持 基本类型('Int32,String和Guid')。

我相信它不喜欢我将一个TPM_USER对象传入Contains()。这可能是有道理的,因为它会产生一个嵌套的SELECT语句,而不是一个IN条款,这或许是EF不能够做到的事情。但是,当然有一种方法来做这样的查询,对吧?

注:如果你很聪明,你可能要问我为什么不只是查询TPM_USERTASKS然后在匹配TPM_TASK,而不是加入。好吧,我爱做到这一点。不过,我一直试图让EF生成一个TPM_USERTASK模型,它根本不会。该表格显示在模型商店中,我可以根据它定义关系。它不会显示在我可以从数据库添加或刷新的实体列表中,我甚至尝试删除整个.EDMX文件并重新创建它。我猜想一些在多对多关系中使用的东西不能也是一个独立的实体吗?

+1

许多一对多的关系不会产生实体。您无法通过整个对象进行搜索,因此您必须比较构成密钥的原始字段。你能发布TPM_TASK和TPM_USER类吗?我很好奇你为什么不能查询TPM_USER表,而是包含TPM_TASK表。 – GWB

回答

2

您的查询会是这个样子:

var tasks = (from t in context.TPM_TASK.Include("TPM_USER") 
      where t.TPM_USER.Any(x => x.Id == user.Id) 
      select t); 

但是,这在某种程度上有点过反正。 TPM_USER对象应该已经具有对TPM_TASK的引用。 所以user.TPM_TASKS应该给你给定用户的所有任务,否则你的模型在某种程度上是错误的。

TASKS多对多用户 意味着: 一个任务,许多用户。 一个用户,很多任务。

还是我错了?

更新

如果你真的想要得到你的模型中TPM_USERTASKS类,你不得不单独的密钥/ ID添加到它。

create table TPM_USERTASKS (
    ID  int identity(1,1) not null 
    UserId int     not null, 
    TaskId int     not null, 
    constraint [PK_TPM_USERTAKS] primary key (ID) 
) 
+0

Doh!不知道为什么'user.TPM_TASKS'没有发生在我身上。这很好用!感谢您的额外解释.. –

2

那么,你必须使用导航属性。

在许多一对多的关系,这意味着你必须在你的TPM_TASK类有

public virtual ICollection<TPM_USER> TpmUsers {get;set;}

和/或

public virtual ICollection<TPM_TASK> TpmTasks{get;set;}

在你TMP_USER类。

如果您不这样做,您将无法编写连接两个实体的查询。

有了这一点,你可以写你的查询作为

var userTasks = context.TPM_TASK 
        .Where(task => task.TpmUsers 
         .Any(user => user.Id == UserId));