需要EF / LINQ查询才能将所有任务分配给特定用户

时间:2012-06-18 18:05:41

标签: c# .net linq entity-framework entity-framework-4

我有一个名为TPM_TASKS的表,其中包含所有任务,以及一个名为TPM_USER的表,其中包含所有用户。然后我有一个名为TPM_USERTASKS的表,其中包含UserIdTaskId,它将一个任务的分配存储到一个用户。

我正在尝试选择分配给给定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文件并再次创建它。我猜想在多对多关系中使用的东西也不能成为一个独立的实体吗?

2 个答案:

答案 0 :(得分: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应该为您提供给定用户的所有任务,否则您的模型会出现问题。

任务多对多用户 手段: 一个任务,很多用户。 一个用户,很多任务。

或者我错了?

<强>更新

如果你真的想在你的模型中获得TPM_USERTASKS类,你必须为它添加一个单独的Key / 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)
)

答案 1 :(得分:2)

好吧,你必须使用导航属性。

在多对多关系中,这意味着您必须拥有

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

在您的TPM_TASK课程中

和/或

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

你在TMP_USER班。

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

这样,您可以将查询编写为

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