Inject TableName as Parameter for Update & Insert on GenericEntity in ServiceStack Ormlite

ⅰ亾dé卋堺 提交于 2019-11-30 21:15:21

问题


I have 3 tables of same structure so i have created the following entity using ServiceStack

public class GenericEntity
{
    [Alias("COL_A")]
    public string ColumnA { get; set; }
}

For retriving the results I use the following line of code. In it I pass the table name like "TableA"/"TableB" so that i can pull the appropriate results

db.Select<GenericEntity>(w => w.Where(whereExperssion).OrderBy(o => o.ColumnA).From("TableA"));

For delete i use the following code

 db.Delete<GenericEntity>(w => w.Where(q => q.ColumnA == "A").From("TableA"));

With From() I can pass table name for SELECT & DELETE operations. Is there a similar way for Inserting and updating? The below is the snippet code I am using for update and insert

Insert

db.Insert(new GenericEntity() {});

Update

db.Update<GenericEntity>(new GenericEntity { ColumnA = "ModifiedData"},p => p.ColumnA == "OriginalData");

回答1:


As you're wanting to this for multiple API's I've added a test showing how to achieve the desired behavior by extending OrmLite's API's with your own custom extension methods that modifies OrmLite's table metadata at runtime to add new API's that allow specifying the table name at runtime, i.e:

var tableName = "TableA"'
db.DropAndCreateTable<GenericEntity>(tableName);

db.Insert(tableName, new GenericEntity { Id = 1, ColumnA = "A" });

var rows = db.Select<GenericEntity>(tableName, q =>
    q.Where(x => x.ColumnA == "A"));

rows.PrintDump();

db.Update(tableName, new GenericEntity { ColumnA = "B" },
    where: q => q.ColumnA == "A");

rows = db.Select<GenericEntity>(tableName, q => 
    q.Where(x => x.ColumnA == "B"));

rows.PrintDump();

With these extension methods:

public static class GenericTableExtensions 
{
    static object ExecWithAlias<T>(string table, Func<object> fn)
    {
        var modelDef = typeof(T).GetModelMetadata();
        lock (modelDef) {
            var hold = modelDef.Alias;
            try {
                modelDef.Alias = table;
                return fn();
            }
            finally {
                modelDef.Alias = hold;
            }
        }
    }

    public static void DropAndCreateTable<T>(this IDbConnection db, string table) {
        ExecWithAlias<T>(table, () => { db.DropAndCreateTable<T>(); return null; });
    }

    public static long Insert<T>(this IDbConnection db, string table, T obj, bool selectIdentity = false) {
        return (long)ExecWithAlias<T>(table, () => db.Insert(obj, selectIdentity));
    }

    public static List<T> Select<T>(this IDbConnection db, string table, Func<SqlExpression<T>, SqlExpression<T>> expression) {
        return (List<T>)ExecWithAlias<T>(table, () => db.Select(expression));
    }

    public static int Update<T>(this IDbConnection db, string table, T item, Expression<Func<T, bool>> where) {
        return (int)ExecWithAlias<T>(table, () => db.Update(item, where));
    }
}

Adding your own extension methods in this way allows you to extend OrmLite with your own idiomatic API's given that OrmLite is itself just a suite of extension methods over ADO.NET's IDbConnection.



来源:https://stackoverflow.com/questions/24955640/inject-tablename-as-parameter-for-update-insert-on-genericentity-in-servicesta

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!