是否可以使用OrmLite生成SQL脚本而不对数据库执行它?我想从一个实时的SqlServer数据库加载一个DTO列表,并输出一个脚本来删除和插入每个记录。
提供的迷你探查器支持日志记录,但看起来需要包装真实的数据库连接。
答案 0 :(得分:1)
直接使用DialectProvider似乎可以满足我的需求。 ToInsertRowStatement
采用IDbCommand
参数,但不使用null
。
OrmLiteConfig.DialectProvider = SqlServerOrmLiteDialectProvider.Instance;
var dto = new PersonDTO { Id = Guid.NewGuid(), Name = "Carl" };
var deleteText = SqlServerOrmLiteDialectProvider.Instance.ToDeleteRowStatement(dto);
var insertText = SqlServerOrmLiteDialectProvider.Instance.ToInsertRowStatement((IDbCommand)null, dto);
有更好的选择吗?
答案 1 :(得分:1)
现在OrmLite extension methods are now mockable提供您自己的OrmLiteResultsFilter,这是微不足道的。
E.g。下面的ResultsFilter记录每个执行的sql语句,并将OrmLiteResultsFilter中的行为设置为inmlite返回空结果:
public class CaptureSqlFilter : OrmLiteResultsFilter
{
public CaptureSqlFilter()
{
SqlCommandFilter = CaptureSqlCommand;
SqlCommandHistory = new List<SqlCommandDetails>();
}
private void CaptureSqlCommand(IDbCommand command)
{
SqlCommandHistory.Add(new SqlCommandDetails(command));
}
public List<SqlCommandDetails> SqlCommandHistory { get; set; }
public List<string> SqlStatements
{
get { return SqlCommandHistory.Map(x => x.Sql); }
}
}
您可以将其包装在使用范围内以捕获每个SQL语句而不执行它们,例如:
using (var captured = new CaptureSqlFilter())
using (var db = OpenDbConnection())
{
db.CreateTable<Person>();
db.Select<Person>(x => x.Age > 40);
db.Single<Person>(x => x.Age == 42);
db.Count<Person>(x => x.Age < 50);
db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse" });
db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" });
db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age",
new { age = 50 });
db.SqlList<Person>("exec sp_name @firstName, @age",
new { firstName = "aName", age = 1 });
db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}"
.SqlFmt("WaterHouse", 7));
var sql = string.Join(";\n\n", captured.SqlStatements.ToArray());
sql.Print();
}
打印出来:
CREATE TABLE "Person"
(
"Id" INTEGER PRIMARY KEY,
"FirstName" VARCHAR(8000) NULL,
"LastName" VARCHAR(8000) NULL,
"Age" INTEGER NOT NULL
);
;
SELECT "Id", "FirstName", "LastName", "Age"
FROM "Person"
WHERE ("Age" > 40);
SELECT "Id", "FirstName", "LastName", "Age"
FROM "Person"
WHERE ("Age" = 42)
LIMIT 1;
SELECT COUNT(*) FROM "Person" WHERE ("Age" < 50);
INSERT INTO "Person" ("Id","FirstName","LastName","Age") VALUES (@Id,@FirstName,@LastName,@Age);
UPDATE "Person" SET "FirstName"=@FirstName, "LastName"=@LastName, "Age"=@Age WHERE "Id"=@Id;
DELETE FROM "Person" WHERE "FirstName"=@FirstName AND "Age"=@Age;
SELECT LastName FROM Person WHERE Age < @age;
exec sp_name @firstName, @age;
UPDATE Person SET LastName='WaterHouse' WHERE Id=7
中提供了更多示例
由于CaptureSqlFilter很有用,我刚刚将其添加到OrmLite in this commit,它将位于下一个 v4.0.20 中,现在是available on MyGet。
答案 2 :(得分:1)
我用这个来捕捉声明并继续运行声明。
public class CustomOrmLiteExecFilter : OrmLiteExecFilter
{
public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter)
{
var holdProvider = OrmLiteConfig.DialectProvider;
var dbCmd = CreateCommand(dbConn);
try
{
var ret = filter(dbCmd);
var pureSQL = holdProvider.MergeParamsIntoSql(dbCmd.CommandText, dbCmd.Parameters.OfType<IDbDataParameter>());
//log or save the SQL Statement
return ret;
}
finally
{
if (OrmLiteConfig.DialectProvider != holdProvider)
OrmLiteConfig.DialectProvider = holdProvider;
}
}
}
和用法:
OrmLiteConfig.ExecFilter = new CustomOrmLiteExecFilter();
希望这可以帮到你!