2

有没有办法在 EF 中使用 ExecuteStoreCommand 执行多个插入语句?我正在使用 StringBuilder 生成多个插入语句。代码基本上是这样的

StringBuilder _saveReasonQuery = new StringBuilder();
public void ApplyRules()
{
    using(var context = new SpecializedDBEntities())
    {
        foreach(var item in list)
        {
            //Do something
            SaveReason(item, reasonId);
        }
        context.GetObjectContext().ExecuteStoreCommand(_saveReasonQuery.ToString());
        ctx.SaveChanges();
    }
}

//Inside Save Reason
public void SaveReason(...)
{
     _saveReasonQuery.Append("INSERT INTO ORDER_IMPLEM_DTL_REASON ");
     _saveReasonQuery.Append("(ORDER_IMPLEM_REASON_ID, SALES_ORDER_IMPLEM_DTL_ID, REASON_ID, REASON_STAT_ID, SALES_ORDER_BRDCST_ID, CREA_BY, CREA_DT)");
     _saveReasonQuery.Append(" VALUES ");
     _saveReasonQuery.Append(String.Format("('0', '{0}', '{1}', '{2}', '{3}', '{4}', TO_DATE('{5}', 'YY-MM-DD HH:mi'));",
                                orderSpot.SALES_ORDER_IMPLEM_DTL_ID, reasonId, Common.Convert_Int64(orderSpot.CUESHT_STAT_ID),
                                orderSpot.SALES_ORDER_DTL_BRDCST_ID, userContext.User.USER_CD, DateTime.Now.ToUniversalTime().ToString("yy-MM-dd hh:mm")));

}

但是,EF 执行查询时会出现 Invalid Character 错误。我做了一些研究,发现是分号产生了这个错误。但我无法删除分号,因为它是 Oracle 的“行尾”。有什么建议么?

此外,我直接针对数据库执行了从 StringBuilder 生成的字符串,它适用于插入 5 行。

4

2 回答 2

1

我通过反复试验找到了解决方案。

事实证明,您需要将多个插入包含在 BEGIN...END 中;语句,以使分号能够被读取为行尾分隔符。

我的代码现在看起来像:

StringBuilder _saveReasonQuery = new StringBuilder();
public void ApplyRules()
{
    using(var context = new SpecializedDBEntities())
    {
        _saveReasonQuery.Append("BEGIN ");
        foreach(var item in list)
        {
            //Do something
            SaveReason(item, reasonId);
        }
        _saveReasonQuery.Append("END;");
        context.GetObjectContext().ExecuteStoreCommand(_saveReasonQuery.ToString());
        ctx.SaveChanges();
    }
}

//Inside Save Reason
public void SaveReason(...)
{
     _saveReasonQuery.Append("INSERT INTO ORDER_IMPLEM_DTL_REASON ");
     _saveReasonQuery.Append("(ORDER_IMPLEM_REASON_ID, SALES_ORDER_IMPLEM_DTL_ID, REASON_ID, REASON_STAT_ID, SALES_ORDER_BRDCST_ID, CREA_BY, CREA_DT)");
     _saveReasonQuery.Append(" VALUES ");
     _saveReasonQuery.Append(String.Format("('0', '{0}', '{1}', '{2}', '{3}', '{4}', TO_DATE('{5}', 'YY-MM-DD HH:mi'));",
                            orderSpot.SALES_ORDER_IMPLEM_DTL_ID, reasonId, Common.Convert_Int64(orderSpot.CUESHT_STAT_ID),
                            orderSpot.SALES_ORDER_DTL_BRDCST_ID, userContext.User.USER_CD, DateTime.Now.ToUniversalTime().ToString("yy-MM-dd hh:mm")));

}
于 2013-07-23T07:43:54.690 回答
0

两者及其名称中所暗示ObjectContext.ExecuteStoreCommand的更新版本DbContext.ExecuteSqlCommand都只会执行一个命令。我建议你在更新语句中构建你的命令,List<>并在它们都准备好时按顺序执行它们......

public void ApplyRules()
{
    var saveQueries = new List<Tuple<string, object[]>>();
    foreach(var item in list)
    {
        //Do something
        saveQueries.Add(SaveQuery(reasonId, ...));
    }

    using(var context = new SpecializedDBEntities())
    {
        foreach(var saveQuery in saveQueries)
        {
            testContext.Database.ExecuteSqlCommand(saveQuery.Item1, saveQuery.Item2);
        }
        ctx.SaveChanges();
    }
}

private Tuple<string, object[]> SaveQuery(int reasonId, ...)
{
    const string query = 
         "INSERT INTO ORDER_IMPLEM_DTL_REASON " +
         "(ORDER_IMPLEM_REASON_ID, SALES_ORDER_IMPLEM_DTL_ID, REASON_ID, REASON_STAT_ID, SALES_ORDER_BRDCST_ID, CREA_BY, CREA_DT)" +
         " VALUES {0}, {0}, {1}, {2}, {3}, {4}, {5}";

    object[] values = new object[]{
        orderSpot.SALES_ORDER_IMPLEM_DTL_ID,
        reasonId,
        Common.Convert_Int64(orderSpot.CUESHT_STAT_ID),
        orderSpot.SALES_ORDER_DTL_BRDCST_ID, 
        userContext.User.USER_CD, 
        DateTime.Now.ToUniversalTime().ToString("yy-MM-dd hh:mm")
    };

    return new Tuple<string, object[]>(query, values);
}
于 2013-07-22T15:27:05.500 回答