Я знаю, что Servicestack.Ormlite настроен как сопоставление 1: 1 между таблицей poco и базой данных. У меня есть ситуация, когда у меня будут группы таблиц, которые имеют одинаковую структуру, и они создаются по мере необходимости. Я пытаюсь найти способ сделать что-то, где я могу продолжать использовать IDbConnection
и указать имя таблицы в CRUD-операциях.ServiceStack.Ormlite single poco map to many tables
Что-то вроде
using(var db = _conn.OpenDbConnection()){
db.SaveAll(objList, "DIFFERENT_TABLE");
}
я легко смог работать вокруг, чтобы сделать создание и удаление таблиц. Я надеюсь, что я смогу использовать ExpressionVisitor
или что-то еще, чтобы помочь изменить имя таблицы до ее выполнения. Одним из требований проекта является то, что он агрегирован в базе данных, поэтому я пытаюсь не вручную выписывать SQL.
Решения Вот несколько функций, которые я создал, если кто-то хочет еще несколько примеров.
public static List<T> SelectTable<T>(this IDbConnection conn, string tableName) {
var stmt = ModelDefinition<T>.Definition.SqlSelectAllFromTable;
stmt = stmt.Replace(ModelDefinition<T>.Definition.Name, tableName.FmtTable());
return conn.Select<T>(stmt);
}
public static List<T> SelectTableFmt<T>(this IDbConnection conn, string tableName, string sqlFilter,
params object[] filterParams) {
var stmt = conn.GetDialectProvider().ToSelectStatement(typeof (T), sqlFilter, filterParams);
stmt = stmt.Replace(ModelDefinition<T>.Definition.Name, tableName.FmtTable());
return conn.Select<T>(stmt);
}
public static void InsertTable<T>(this IDbConnection conn, T obj, string tablename) {
var stmt = conn.GetDialectProvider().ToInsertRowStatement(null, obj);
stmt = stmt.Replace(obj.GetType().Name, tablename.FmtTable());
conn.ExecuteSql(stmt);
}
public static int SaveAll<T>(this IDbConnection conn, string tablename, IEnumerable<T> objs) {
var saveRows = objs.ToList();
var firstRow = saveRows.FirstOrDefault();
if (Equals(firstRow, default(T))) return 0;
var defaultIdValue = firstRow.GetId().GetType().GetDefaultValue();
var idMap = defaultIdValue != null
? saveRows.Where(x => !defaultIdValue.Equals(x.GetId())).ToSafeDictionary(x => x.GetId())
: saveRows.Where(x => x.GetId() != null).ToSafeDictionary(x => x.GetId());
var existingRowsMap = conn.SelectByIds<T>(tablename, idMap.Keys).ToDictionary(x => x.GetId());
var modelDef = ModelDefinition<T>.Definition;
var dialectProvider = conn.GetDialectProvider();
var rowsAdded = 0;
using (var dbTrans = conn.OpenTransaction()) {
foreach (var obj in saveRows) {
var id = obj.GetId();
if (id != defaultIdValue && existingRowsMap.ContainsKey(id)) {
var updStmt = dialectProvider.ToUpdateRowStatement(obj);
updStmt = updStmt.Replace(obj.GetType().Name, tablename.FmtTable());
conn.ExecuteSql(updStmt);
}
else {
if (modelDef.HasAutoIncrementId) {}
var stmt = dialectProvider.ToInsertRowStatement(null, obj);
stmt = stmt.Replace(obj.GetType().Name, tablename.FmtTable());
conn.ExecuteSql(stmt);
rowsAdded++;
}
}
dbTrans.Commit();
}
return rowsAdded;
}
Это действительно работает в ServiceStack 3.9.71. Он не работает в ServiceStack 4.0.6 –
@mnfact Это странно, что он все равно должен работать. Мне нужно взглянуть на последнюю версию кода и посмотреть, что изменилось. – Scott
Я тоже посмотрю. Скорее всего, он просто проскочил через конверсию. –