C# 使用Dapper.Contrib插入和多重映射

C# 使用Dapper.Contrib插入和多重映射,c#,sqlite,dapper,dapper-contrib,C#,Sqlite,Dapper,Dapper Contrib,我试图做的是能够使用复杂对象进行检索和写回数据库 例如,我有两个班 [Table("Children")] public class Child { public int Id { get; set; } public int ParentId { get; set; } public string Data { get; set; } } [Table("Parents")] public class Parent { public int Id { get;

我试图做的是能够使用复杂对象进行检索和写回数据库

例如,我有两个班

[Table("Children")]
public class Child
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Data { get; set; }
}

[Table("Parents")]
public class Parent
{
    public int Id { get; set; }
    public string Data { get; set; }
    public List<Child> Children { get; set; }

    public Parent()
    {
        Children = new List<Child>();
    }
}
[表(“子项”)]
公营儿童
{
公共int Id{get;set;}
public int ParentId{get;set;}
公共字符串数据{get;set;}
}
[表(“家长”)]
公共类父类
{
公共int Id{get;set;}
公共字符串数据{get;set;}
公共列表子项{get;set;}
公共家长()
{
Children=新列表();
}
}
我使用下面的方法填充父对象

public List<Parent> GetAll()
{
    var parents = new List<Parent>();
    using (SQLiteConnection conn = new SQLiteConnection(sqlConnectionString))
    {
        string sql = $@"
        SELECT * From Parents;
        SELECT * FROM Children;
        ;";

        var results = conn.QueryMultiple(sql);
        parents = results.Read<Parent>().ToList();
        var children = results.Read<Child>();
        foreach (var parent in parents)
        {
            parent.Children = children.Where(a => a.ParentId == parent.Id).ToList();
        }
    }
  return parents;
}
public List GetAll()
{
var parents=新列表();
使用(SQLiteConnection conn=newsqliteconnection(sqlConnectionString))
{
字符串sql=$@”
从家长中选择*;
从子项中选择*;
;";
var results=conn.QueryMultiple(sql);
parents=results.Read().ToList();
var children=results.Read();
foreach(父对象中的var父对象)
{
parent.Children=Children.Where(a=>a.ParentId==parent.Id).ToList();
}
}
返回父母;
}
我的问题是,既然我有了填充的对象,我想对父对象进行更改,包括添加/更新/删除Parent.Children中的值

这是我第一次使用update方法,但我认识到这里存在一些问题,例如根据子Id是否为零来确定更新或插入,以及这有点冗长

有没有办法,我是否缺少Dapper或Dapper.Contrib的一些功能,这些功能可以提供帮助方法,使这个过程更简单?

public bool Update(Parent parent)
{
    bool result = true;
    using (SQLiteConnection conn = new SQLiteConnection(sqlConnectionString))
    {
        conn.Open();
        using (var tran = conn.BeginTransaction())
        {
            try
            {
                if (!conn.Update<Parent>(parent))
                {
                    result = false;
                }

                foreach (var element in parent.Children)
                {
                    if (element.Id == default(int))
                    {
                        conn.Insert<Child>(element);
                    }
                    else
                    {
                        if (!conn.Update<Child>(element))
                        {
                            result = false;
                        }
                    }
                }
                tran.Commit();
            }
            catch(Exception ex)
            {
                //logger.Error(ex,"error attempting update");
                tran.Rollback();
                throw;
            }
        }
    }

    return result;
}
公共bool更新(父级)
{
布尔结果=真;
使用(SQLiteConnection conn=newsqliteconnection(sqlConnectionString))
{
conn.Open();
使用(var tran=conn.BeginTransaction())
{
尝试
{
如果(!conn.Update(父级))
{
结果=假;
}
foreach(parent.Children中的var元素)
{
if(element.Id==默认值(int))
{
连接插件(元件);
}
其他的
{
如果(!conn.Update(元素))
{
结果=假;
}
}
}
trans.Commit();
}
捕获(例外情况除外)
{
//logger.Error(例如,“尝试更新时出错”);
事务回滚();
投掷;
}
}
}
返回结果;
}

遗憾的是,考虑到对这个问题的回答有多差,以及一般的短小精悍的问题。我决定抛弃整洁,转而使用更适合我需要的ORM。感谢所有提供建议的人。

也许你只需要在已经实现这些东西的地方使用更“重”的ORM式实体框架?不幸的是,现有的需求使得实体不太可能实现,vs2017、sqlite和EF都没有发挥好,而且在很长一段时间内不太可能。你是说sqlite的EF提供程序会生成错误的查询?那奈特呢?因为“能够使用复杂对象进行检索和写回数据库”基本上就是“重型”ORM的全部内容。不,基本上是对visual studio 2017设计时安装程序的更改,导致sqlite团队至少目前放弃了对设计时组件的支持。在没有他们的情况下管理EF,在我们内部,这被认为比没有他们的情况下实施更麻烦。如果我不能用Dapper获得任何其他答案,我将调查NHibernate。至于我,不需要设计师支持。这里有代码优先,或者您可以先将数据库构建为您不喜欢代码的类的模型。另外,EF core(也可以在完整的.NET中使用)支持SQLite(虽然也没有设计器,但根本没有对EF core的设计器支持,人们仍然很乐意使用它)。对不起,我正是处于这种情况……在Dapper?Entity Framework之后,你指了什么,它也有它的挑战,在vs2017上的设置有点痛苦,但总的来说,它满足了我的需要。