3
我知道Servicestack.Ormlite設置爲poco和數據庫表之間的1:1映射。我有一種情況,我將擁有相同結構的表組,並根據需要創建它們。我試圖找到一種方法來做一些事情,我可以繼續使用IDbConnection
並在CRUD操作中指定表名。ServiceStack.Ormlite將單個poco映射到很多表
喜歡的東西
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
我也來看看吧。機會只是通過轉換而下滑。 –