首页 > 解决方案 > 使用实体框架从多个表中检索数据

问题描述

我想从多个表中获取数据itemId每个表从多个表中获取数据。

目前,我有一个 item 表,其中的一ItemId列与另一个名为 1:m 的表有关系ExplicitMods

namespace Poe.Models
{
    public class Item
    {
        [Key]
        public string ItemId { get; set; }
        public List<ExplicitMod> ExplicitMods { get; set; }
    }
}

namespace Poe.Models
{
    public class ExplicitMod       
    {
        public ExplicitMod(string Name)
        {
            this.Name = Name;
        }

        [Key]
        public string ItemId { get; set; } 
        public string Name { get; set; }
    }
}

我还设置了两个表的上下文:

namespace Poe.DataAccess
{
    public class DatabaseContext : DbContext
    {
        public DbSet<Item> Items { get; set; }
        public DbSet<ExplicitMod> ExplicitMod { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
        }
    }
}

然后我尝试调用项目表,搜索一个名为“Brood Star”的随机名称,并加入显式Mod 表:

public static void Search()
{
    //return FindItems(i);
    using (var db = new DatabaseContext())
    {
        var blogs = db.Items
                    .Where(b => b.Name.Equals("Brood Star"))
                    .Include(es => es.ExplicitMods).ToList();
        Debug.Write(blogs);
    }
}

我应该怎么做才能得到一张桌子的结果?

我也收到此错误:

System.Data.SqlClient.SqlException:'无效的对象名称'ExplicitMod'

标签: c#.netentity-framework

解决方案


您的参考资料需要稍作调整。对于 1-many,您的 ExplicitMod 将需要它自己的 PK 和 Item 的 FK:

public class ExplicitMod       
{
    public ExplicitMod()
    {}

    public ExplicitMod(string name)
    {
        Name = name;
    }

    [Key]
    public string ExplicitModId { get; set; } 
    [ForeignKey("Item")]
    public string ItemId{ get; set; }
    public string Name { get; set; }
    public virtual Item Item { get; set; }
}

我相信它还需要一个无参数的构造函数,以便 EF 能够即时构造这些。您可能能够摆脱受保护或私有的构造函数。

对于项目:

public class Item
{
   [Key]
    public string ItemId { get; set; }
    public virtual ICollection<ExplicitMod> ExplicitMods { get; private set; } = new List<ExplicitMod>();
}

建议初始化集合并使用私有设置器,以便在创建要填充的新实体以及让外部代码将集合引用设置为新的未跟踪实体集时节省步骤。(对于单元测试,我通常将 setter 标记为内部以允许单元测试设置存根)

我强烈建议对 PK/FK 字段使用intorGuid而不是字符串。如果您想拥有唯一的标识字符串,请将它们添加为附加列 /w 唯一约束。使用数字或 UUID 键是“无意义键”的一种形式,它可以节省索引空间并使修改值更容易,而不必担心意外更改/使数据关系无效。


推荐阅读