2014-01-13 2 views
3

Я знаю, что 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; 
    } 

ответ

2

OrmLite поддерживает указание имени таблицы для операций обновления и удаления. К сожалению, примеры в readme here еще не обновлены. Это требуется Формат:

UPDATE:

db.UpdateFmt(table: "Person", set: "FirstName = {0}".Fmt("JJ"), where: "LastName = {0}".Fmt("Hendrix")); 

УДАЛЕНИЕ:

db.DeleteFmt(table: "Person", where: "Age = {0}".Fmt(27)); 

методы, которые нужно может быть found here. Вы должны иметь возможность использовать .Exec для обработки операций чтения и вставки.

+0

Это действительно работает в ServiceStack 3.9.71. Он не работает в ServiceStack 4.0.6 –

+0

@mnfact Это странно, что он все равно должен работать. Мне нужно взглянуть на последнюю версию кода и посмотреть, что изменилось. – Scott

+0

Я тоже посмотрю. Скорее всего, он просто проскочил через конверсию. –

 Смежные вопросы

  • Нет связанных вопросов^_^