繁体   English   中英

如何根据另一个实体过滤一个实体? Linq C#中的多对多

[英]How do I filter an entity based on another entity? Linq many-to-many in C#

这在SQL中很容易做到,而使用Linq to SQL实现此目标非常困难。 我有两个实体设置,即Project和ProjectsbyUser:

[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())。 这必须很容易做到,但是我没有想出一种无需编写糟糕代码即可完成它的方法。 这篇博客文章解释了我想做的事情,但似乎使用了“ Linq to SQL类”模板,现在我的实体位于漂亮的C#类文件中,而不是在VS2008精美的GUI设计器文件中。 必须有一种优雅的方法来解决这个问题,我已经为此工作了大约一个星期,并认为我可能会陷入困境。 谢谢你的帮助!

旁注:您要做两次ToList(),这不是必需的:)

回答您的问题:

在ProjectList和Project之间创建一个父级关联,以便每个ProjectList项都有一个名为“ Project”的属性(或任何您想调用的属性)。

然后,只需执行以下操作:

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

...还有bam,您有该用户的项目列表。

编辑:另一个对子关系有效的解决方案也可以使用,但我认为这更干净,如果您对查询进行概要分析,则实际上更有效。 另一个解决方案最终是在内部进行昂贵的连接。

这会满足您的需求吗?

projectsRepository.Projects
    .Where( x1 => x1.ProjectId == "H1000" &&
        x1.ProjectList.Any( x2 => x2.UserId == User.Identity.Name.ToString() ) )
    .ToList()
string userID = User.Identity.Name.ToString();
var query = from p in repository.Projects
        from pl in p.ProjectList
        where pl.UserID = userID
        select p;

也许这种方式是最易读的。

我想我以未注册用户的身份提出了问题,似乎无法登录并正确标记最佳答案。 对于后代,Mike Maryonwski的方法效果很好,避免了我试图避免的不必要的连接。 我添加到myproject实体的唯一代码:

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

根据SQL Profiler的描述,它运行非常高效,仅提取所需的内容(我想这很重要,但我仍然很惊讶它不会生成混乱的TSQL语句)。 Misha的方法看起来也可以使用,但是我更喜欢Lambda表达式和Mike的风格而不是“ inverted SQL”语句。 在我看来,这很不对劲,但是我一直在写TSQL。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM