gpt4 book ai didi

ServiceStack.Ormlite 单个 poco 映射到多个表

转载 作者:行者123 更新时间:2023-12-02 01:54:12 24 4
gpt4 key购买 nike

我知道 Servicestack.Ormlite 设置为 poco 和数据库表之间的 1:1 映射。我有这样一种情况,我将拥有结构相同的表组,并且它们是根据需要创建的。我正在尝试找到一种方法,以便能够继续使用 IDbConnection 并在 CRUD 操作中指定表名。

有点像

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;
}

最佳答案

OrmLite 支持为Update 和Delete 操作指定表名。不幸的是 readme here 中的示例尚未更新。这是必需的格式:

更新:

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 来处理读取和插入操作。

关于ServiceStack.Ormlite 单个 poco 映射到多个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21099597/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com