2009-10-20 37 views
0

这在SQL中很容易实现,我很难用Linq to SQL实现这一点。我有两个实体的建立,项目和ProjectsbyUser:如何根据另一个实体过滤实体? Linq多对多C#

[Table(Name = "Projects")] 
public class Project 
{ 
    [Column(IsPrimaryKey = true, IsDbGenerated = true, Name="Job")] 
    public string ProjectId { get; set; } 
    [Column(Name = "Description")] 
    public string Description { get; set; }   

    [Association(OtherKey = "ProjectId")] 
    private EntitySet<ProjectList> _projectlist = new EntitySet<ProjectList>(); 
    public IEnumerable<ProjectList> ProjectList { get { return _projectlist; } } 
} 

[Table(Name = "ProjectLists")] 
public class ProjectList 
{ 
    [Column(IsPrimaryKey = true)] 
    public string UserId { get; set; } 
    [Column(IsPrimaryKey = true)] 
    public string ProjectId { get; set; } 
} 

所以在我ProjectsController我也会有这样的:

public ViewResult myProject() 
    { 
     var query = projectsRepository.Projects 
         .Where(x => x.ProjectId == "H1000").ToList(); 
     return View(query.ToList()); 
    } 

哎,你怎么知道,它会显示所有连接到用户项目H1000与我的观点内嵌几个很好的嵌套的foreach语句。尽可能简单,但我试图根据用户进行过滤。我可以让用户足够简单(与UserId列匹配的User.Identity.Name.ToString())。这很容易做到,但我没有想出一个方法来完成它,而不写出可怕的代码。这个blog post解释了我想要做的事情,但它似乎使用“Linq to SQL classes”模板,现在我的实体坐在漂亮的C#类文件中,而不是在VS2008华丽的GUI设计器文件中。必须有一个优雅的方式来解决这个问题,我已经为此工作了大约一周,并认为我可能会让自己陷入一个角落。谢谢你的帮助!

回答

0

这是否做你所需要的?

projectsRepository.Projects 
    .Where(x1 => x1.ProjectId == "H1000" && 
     x1.ProjectList.Any(x2 => x2.UserId == User.Identity.Name.ToString())) 
    .ToList() 
1

旁注:你正在做ToList()两次,这是没有必要的:)

回答你的问题:

创建ProjectList和项目之间的家长协会,使每个ProjectList项目有一个名为“项目”(或任何你想调用它)的属性。

然后,就这样做:

string userId = User.Identity.Name.ToString(); 
var query = projectsRepository.ProjectLists.Where(pl => pl.UserId == userId).Select(pl => pl.Project); 

......然后砰一声,你有项目,该用户的列表。

编辑:另一个解决方案张贴在儿童关系上的作品也将工作,但在我看来这是更清洁,如果你剖析查询,它实际上是更有效的。另一种解决方案最终在内部进行昂贵的连接。

0
string userID = User.Identity.Name.ToString(); 
var query = from p in repository.Projects 
     from pl in p.ProjectList 
     where pl.UserID = userID 
     select p; 

也许这种方式是最具可读性的。

0

我想我问这个问题是一个未注册的用户,似乎无法登录并正确标记最佳答案。为了后人迈克·玛洛诺夫斯基的方法工作得很好,并避免了我试图避免的不必要的连接。唯一的代码,我加入到MyProject的实体:

[Association(ThisKey = "ProjectId")] 
public Project Project { get; set; } 

根据SQL事件探查器运行非常有效,仅拉动需要什么(我猜是那种一点,但我仍然感到惊讶它不生成凌乱的TSQL语句)。 Misha的方法看起来也可以工作,但我更喜欢Mike的“Lambda表达式”和“反向SQL”语句的风格。它看起来很错,但我一直在写TSQL。