Asp.net 在dapper中使用一对多关系时发生splitOn错误

Asp.net 在dapper中使用一对多关系时发生splitOn错误,asp.net,dapper,Asp.net,Dapper,我试图使用dapper的多重映射功能返回菜单类别和关联菜单的列表。但我得到以下错误:- 使用多重映射API时,请确保在以下情况下设置splitOn参数 你有身份证以外的钥匙 以下是我的课程:- VMMenuCategory.cs public class VMMenuCategory { public int MenuCategoryID { get; set; } public string CategoryName { get; set; }

我试图使用dapper的多重映射功能返回菜单类别和关联菜单的列表。但我得到以下错误:-

使用多重映射API时,请确保在以下情况下设置splitOn参数 你有身份证以外的钥匙

以下是我的课程:-

VMMenuCategory.cs

public class VMMenuCategory
    {
        public int MenuCategoryID { get; set; }
        public string CategoryName { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }


        public List<VMMenu> Menus { get; set; }
    }
 public class VMMenu
    {
        public int MenuID { get; set; }
        public int MenuCategoryID { get; set; }
        public string ProductName { get; set; }
        public int? CostPrice { get; set; }
        public int? SellingPrice { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }

    }
public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
    {


        List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
        {
            List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
            string query = "select * from [dbo].[MenuCategories]";
            using (var connection = GetConnection())
            {
                var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(query, map:(mc,m) => { mc.Menus =new List<VMMenu>() ;return mc; },splitOn: "MenuID").ToList();
                return data;
            }
            //return _lstVMMenuCategory;
        }
    }
MenuCategoriesRepository.cs

public class VMMenuCategory
    {
        public int MenuCategoryID { get; set; }
        public string CategoryName { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }


        public List<VMMenu> Menus { get; set; }
    }
 public class VMMenu
    {
        public int MenuID { get; set; }
        public int MenuCategoryID { get; set; }
        public string ProductName { get; set; }
        public int? CostPrice { get; set; }
        public int? SellingPrice { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }

    }
public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
    {


        List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
        {
            List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
            string query = "select * from [dbo].[MenuCategories]";
            using (var connection = GetConnection())
            {
                var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(query, map:(mc,m) => { mc.Menus =new List<VMMenu>() ;return mc; },splitOn: "MenuID").ToList();
                return data;
            }
            //return _lstVMMenuCategory;
        }
    }
公共密封类MenuCategoryRepository:连接,IMenuCategoryRepository
{
列出IMenuCategoryRepository.GetAllMenuCategories()
{
列表lstVMMenuCategory=新列表();
string query=“从[dbo].[MenuCategories]中选择*”;
使用(var connection=GetConnection())
{
var data=connection.Query(Query,map:(mc,m)=>{mc.Menus=newlist();return mc;},splitOn:“MenuID”).ToList();
返回数据;
}
//返回lstVMMenuCategory;
}
}

为了用两个表中的数据填充两个对象,您必须查询两个表。在您的情况下,它很可能是一个内部连接:

public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
{
    List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
    {
        List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
        string query = @"
            select mc.*, m.*
            from [dbo].[MenuCategories] mc,
            join [dbo].[Menus] m on mc.MenuCategoryID = m.MenuCategoryID
        ";
        using (var connection = GetConnection())
        {
            var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(
               query,
               map:(mc,m) => {
                   var foundMc = _lstVMMenuCategory
                       .FirstOrDefault(x => x.MenuCategoryID = mc.MenuCategoryID);
                   if (foundMc == null) {
                       foundMc = mc;
                       foundMc.Menus = new List<VMMenu>() ;
                   }
                   foundMc.Menus.Add(m);
                   return mc; 
               },
               splitOn: "MenuID").ToList();
        }
        return _lstVMMenuCategory;
    }
}
公共密封类MenuCategoryRepository:连接,IMenuCategoryRepository
{
列出IMenuCategoryRepository.GetAllMenuCategories()
{
列表lstVMMenuCategory=新列表();
字符串查询=@“
选择mc.*,m*
来自[dbo][MenuCategories]mc,
在mc.MenuCategoryID=m.MenuCategoryID上加入[dbo].[Menus]m
";
使用(var connection=GetConnection())
{
var data=connection.Query(
查询
映射:(mc,m)=>{
var foundMc=lstVMMenuCategory
.FirstOrDefault(x=>x.MenuCategoryID=mc.MenuCategoryID);
if(foundMc==null){
foundMc=mc;
foundMc.Menus=新列表();
}
foundMc.Menus.Add(m);
返回mc;
},
splitOn:“MenuID”).ToList();
}
返回lstVMMenuCategory;
}
}
注意:我猜到了第二个表名,并且还假设
MenuID
菜单中位于表定义的第一位。但是,最好在select子句中明确列出所有必需的列


我还稍微修改了mapper函数,以避免在categories集合中出现重复项。

为了填充分层数据,我更改了方法

代码如下:

public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
    {
        List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
        {
            List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
            string query = @"
            select mc.*, m.*
            from [dbo].[MenuCategories] mc
            join [dbo].[Menu] m on mc.MenuCategoryID = m.MenuCategoryID";
            using (var connection = GetConnection())
            {
                var vmMenuCategoryDictionary = new Dictionary<int, VMMenuCategory>();
                var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(
                   query,
                   map: (mc, m) =>
                   {
                       VMMenuCategory _VMMenuCategory;
                       if(!vmMenuCategoryDictionary.TryGetValue(mc.MenuCategoryID,out _VMMenuCategory))
                       {
                           _VMMenuCategory = mc;
                           _VMMenuCategory.Menus = new List<VMMenu>();
                           vmMenuCategoryDictionary.Add(_VMMenuCategory.MenuCategoryID, _VMMenuCategory);

                       }
                       _VMMenuCategory.Menus.Add(m);                   
                       return _VMMenuCategory;
                   },
                   splitOn: "MenuID").Distinct().ToList();
                _lstVMMenuCategory = data;
            }
            return _lstVMMenuCategory;
        }
    }
公共密封类MenuCategoryRepository:连接,IMenuCategoryRepository
{
列出IMenuCategoryRepository.GetAllMenuCategories()
{
列表lstVMMenuCategory=新列表();
字符串查询=@“
选择mc.*,m*
来自[dbo][MenuCategories]mc
在mc.MenuCategoryID=m.MenuCategoryID上加入[dbo]。[Menu]m;
使用(var connection=GetConnection())
{
var vmMenuCategoryDictionary=新字典();
var data=connection.Query(
查询
映射:(mc,m)=>
{
VMMenuCategoryu VMMenuCategory;
if(!vmMenuCategoryDictionary.TryGetValue(mc.MenuCategoryID,outvmmenucategory))
{
_VMMenuCategory=mc;
_VMMenuCategory.Menus=新列表();
添加(_-VMMenuCategory.MenuCategoryID,_-VMMenuCategory);
}
_VMMenuCategory.Menus.Add(m);
返回(VMMenuCategory);
},
splitOn:“MenuID”).Distinct().ToList();
_lstVMMenuCategory=数据;
}
返回lstVMMenuCategory;
}
}

看起来像
[dbo].[MenuCategories]
表没有
MenuID
列。@DmitryEgorov,是的,它是一个子表。我尝试了
splitOn:“MenuCategoryID”
但是我得到了相同的错误。然后你需要在这个查询中连接这两个表。@DmitryEgorov,所以没有连接是无法做到的。当实体框架在ORM中工作时?恐怕不行。Dapper不知道在哪里可以找到
VMMenu
的数据,除非你在查询中告诉它。我已经对你的答案进行了投票。谢谢你节省了我的时间。你太棒了。我没有得到想要的结果。我需要菜单类别下的菜单。基本上我需要层次数据,但我得到每个菜单的菜单类别。但是我需要一个包含多个菜单的菜单目录。实际上sql查询的结果是相同的。