【问题标题】:MVC - Linq - Populate List<T> with Records in Another TableMVC - Linq - 用另一个表中的记录填充列表<T>
【发布时间】:2009-09-18 17:27:58
【问题描述】:

我正在制作我的第一个 MVC 应用程序的原型,它是一个简单的论坛。我已经完成了域模型的一部分,并且试图弄清楚如何仅在 SQL 中做一些非常基本的事情,但我无法在我的应用程序中弄清楚。这是我的实体:

[Table(Name="Users")]
public class User
{
    [Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)]
    public int Id { get; set; }

    [Column] public string Username { get; set; }
    [Column] public string Password { get; set; }
    [Column] public string PasswordHash { get; set; }
    [Column] public string PasswordSalt { get; set; }
    [Column] public string FirstName { get; set; }
    [Column] public string LastName { get; set; }
    public List<Forum> AllowedForums { get; set; }
    [Column] public DateTime LastLogin { get; set; }
    [Column] public DateTime MemberSince { get; set; }
}

[Table(Name="Forums")]
public class Forum
{
    [Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)]
    public int Id { get; set; }
    [Column] public int ParentId { get; set; }
    [Column] public string Title { get; set; }
    [Column] public string Description { get; set; }
    [Column] public bool IsGlobal { get; set; }
    [Column] public int DisplayOrder { get; set; }
}

我还有一个名为 AllowedForums 的链接表,如下所示:

userid  forumid
  1       4

为了选择允许用户查看的论坛和 IsGlobal == true 的论坛,我会在 SQL 中执行此操作:

SELECT * FROM Forums
LEFT OUTER JOIN AllowedForums ON Forums.id = AllowedForums.Forumid
WHERE AllowedForums.Userid = 1
OR Forums.IsGlobal = 1

我应该如何填充

public List<Forum> AllowedForums

使用 C#/Linq to SQL 的字段?

AllowedForum 应该是一个具有自己的表映射的值对象吗?这似乎有点矫枉过正,但我​​可以轻松加入。我简要地查看了 EntitySet,但我看到的简单示例似乎不合适。感觉应该有一种优雅的方式来为每个用户获取论坛对象的集合,但我想不出任何方法。顺便说一句,我是 C# 和 OO 的新手。我还应该提到,由于这些是应用程序的早期阶段,如果我没有看到更好的方法,我愿意更改实体或表的结构/关系。

【问题讨论】:

    标签: c# asp.net-mvc linq linq-to-sql domain-driven-design


    【解决方案1】:

    您应该有另一个实体类(可能应该是内部的)来反映数据库中的 AllowedForums 表。现在我假设您的 User 表和 Forums 表都与此 AllowedForums 表具有 PK/FK 关系。因此,User 类应该有一个内部属性,如下所示:

    internal EntitySet<AllowedForums> AllowedForumsRelationships
    {
       get;set;
    }
    

    或者类似的东西。这应该在 User 和 Forums 类上。您的 AllowedForums 类将有两个属性。一个用于用户,一个用于论坛。 (如果您使用 LINQ to SQL 设计器,这一切都会自动为您完成)。

    一旦你有了它,如果你想为用户获取所有 AllowedForums,你可以这样做:

        public IList<Forum> AllowedForums
        {
           get
           {
              var result = new List<Forum>();
              foreach(var relationShip in this.AllowedForumsRelationships)
              {
                 result.Add(relationShip.Forum);
                 return result;
              }
           }
        }
    

    这是我刚刚敲出的一些粗略代码,我不确定它是否 100% 准确,但我想你会明白的。基本上,您正在处理多对多的关系,这总是很痛苦。

    编辑:我只是在 Northwind 数据库中用这些表搞砸了这个想法:

    订单 订单详细信息 产品

    这里是多对多的关系:一个订单可以有多个产品,一个产品可以属于多个订单。现在假设您要获取订单的所有产品:

    public partial class Order
    {
            public IList<Product> Products
            {
                get
                {
                    var list = new List<Product>();
                    foreach (var item in this.Order_Details)
                    {
                        list.Add(item.Product);
                    }
                    return list;
                }
            }
     }
    

    这行得通,所以它也应该适用于您正在谈论的场景。

    【讨论】:

    • 在第一次迭代期间不会退出 foreach 吗?
    • 类似于 get { return from r in AllowerForumsRelationship select r.Forum; }
    • 我想我有足够的时间来试试这个。我会告诉你进展如何。
    • 我得出的结论是,我在我的头上。我将使用拖放 dbml 方法。尝试使用完整的 DDD/TDD 来尝试您的第一个 .net/OO/C#/Linq/MVC 项目,而所有这些对我来说太过分了。一个月内要发货!所以,我确实认为你的回答是正确的,我已经给你投票了。谢谢你的帮助。也许几个月后我会重构并再试一次。
    【解决方案2】:

    类似:

    var AllowedForums = from f in ForumsTable
                        join af in AllowedForumsTable on f.Id equals af.forumid into temp
                        from aft in temp.DefaultIfEmpty()
                        where (f.IsGlobal == 1 || aft.userid == 1)
                        select f;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      相关资源
      最近更新 更多