- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
TLDR:
The following code is run in the different databases, Oracle:
select sysdate from dual
SQLiteselect datetime('now')
When doing
Session.CreateSQLQuery(cmd).UniqueResult<DateTime>()
the result is a DateTime when working against Oracle but a string when working against SQLite.It feels like a bug in the SQLite driver and a hack to check the returned type and do a DateTime.Parse() if it is a string. I could do that but are there any ways to have NHibernate return the correct type?
我正在尝试从数据库中获取当前数据库时间。它在使用 Oracle 时工作正常,但当我尝试针对 SQLite 执行此操作时(在我的单元测试中)它会中断,因为返回的日期不是 DateTime 而是一个字符串。
我见过使用自定义 IUserType 的解决方案,但我看不出在这种情况下应该如何使用它。有什么建议吗?
using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Dialect.Function;
namespace My.Common.Types {
public class MyNHibernateDialectException : Exception {
public MyNHibernateDialectException(string message) : base(message) { }
}
/// <summary>
/// Define all custom functions here by name. It is important that when adding a new custom sql function, that function will work
/// in all dialects supported.
/// </summary>
public static class MyDatabaseDialects {
public enum Query {
SysDate
}
/// <summary>
/// Dialect implementations will use this function to verify that they all implement the same functions.
/// </summary>
/// <param name="dialect"></param>
public static void VerifyRegistrations(this NHibernate.Dialect.Dialect dialect) {
// Verify that the required function are there
foreach (var func in Enum.GetValues(typeof(Function))) {
var enumName = func.ToString();
if (!dialect.Functions.ContainsKey(enumName)) {
throw new MyNHibernateDialectException(
string.Format("The custom function '{0}' is not defined. Did you forget it in factory '{1}'?", enumName, dialect));
}
}
}
}
/// <summary>
/// An interface to reveal more advanced functionality that is database specific
/// </summary>
public interface IDialectExtensions {
/// <summary>
/// Fetch a query specfic for the current database.
/// </summary>
ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query);
/// <summary>
/// Fetch a parameterized query specfic for the current database.
/// </summary>
ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query, params object[] queryParams);
}
/// <summary>
/// Class to store database specific objects except functions (which are supported by NHibernate).
/// </summary>
class DialectExtension {
private readonly Dictionary<MyDatabaseDialects.Query, string> queryDictionary = new Dictionary<MyDatabaseDialects.Query, string>();
public ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query) {
return this.GetQuery(session, query, null);
}
public ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query, params object[] queryParams) {
var cmd = (queryParams == null) ? queryDictionary[query] : string.Format(queryDictionary[query], queryParams);
return session.Session.CreateSQLQuery(cmd);
}
public void RegisterQuery(MyDatabaseDialects.Query query, string hqlString) {
queryDictionary.Add(query, hqlString);
}
public void VerifyQueryRegistrations() {
foreach (var query in Enum.GetValues(typeof(MyDatabaseDialects.Query))) {
if (!queryDictionary.ContainsKey((MyDatabaseDialects.Query)query)) {
throw new MyNHibernateDialectException(string.Format("The custom query '{0}' is not defined.", query.ToString()));
}
}
}
}
public class MyOracle10gDialect : NHibernate.Dialect.Oracle10gDialect, IDialectExtensions {
private readonly DialectExtension dialectExtension = new DialectExtension();
public MyOracle10gDialect() {
#region Dialect extensions
dialectExtension.RegisterQuery(MyDatabaseDialects.Query.SysDate, @"select sysdate from dual");
dialectExtension.VerifyQueryRegistrations();
#endregion Dialect extensions
}
public ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query) {
return dialectExtension.GetQuery(session, query);
}
public ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query, params object[] queryParams) {
return dialectExtension.GetQuery(session, query, queryParams);
}
}
public class MySqliteDialect : NHibernate.Dialect.SQLiteDialect, IDialectExtensions {
private readonly DialectExtension dialectExtension = new DialectExtension();
public MySqliteDialect() {
#region Dialect extensions
dialectExtension.RegisterQuery(MyDatabaseDialects.Query.SysDate, @"select datetime('now')");
dialectExtension.VerifyQueryRegistrations();
#endregion Dialect extensions
}
public ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query) {
return dialectExtension.GetQuery(session, query);
}
public ISQLQuery GetQuery(ISession session, MyDatabaseDialects.Query query, params object[] queryParams) {
return dialectExtension.GetQuery(session, query, queryParams);
}
}
}
我像这样使用上面的代码:
/// <summary>
/// Fetches a DialectExtensions object allowing us to have more advanced functionality that is database specific
/// </summary>
public static IDialectExtensions GetDialectExtensions(this IOperationContext operationContext) {
return Session.GetSessionImplementation().Factory.Dialect as IDialectExtensions;
}
/// <summary>
/// Get the database time by executing a raw SQL statement.
/// </summary>
public static DateTime? GetDatabaseTime() {
DateTime? result = null;
try {
result = GetDialectExtensions()
.GetQuery(Session, MyDatabaseDialects.Query.SysDate)
.UniqueResult<DateTime>();
} catch {
// SQLite will throw exception here as the result is returned as a string instead of a DateTime
}
return result;
}
最佳答案
When doing Session.CreateSQLQuery(cmd).UniqueResult() the result is a DateTime when working against Oracle but a string when working against SQLite.
听起来您可能需要进一步修改 SQLite 的休眠方言以返回相同的结果。确保为 SQLite 设置了默认的列映射类型,以匹配返回的 Oracle。我将时间戳列映射到日期时间。这是我的 SQLiteDialect,请记住这是一个 Java 版本,但应该仍然相似:
public class SQLiteDialect extends Dialect {
public SQLiteDialect() {
super();
registerColumnType(Types.BIT, "integer");
registerColumnType(Types.TINYINT, "tinyint");
registerColumnType(Types.SMALLINT, "smallint");
registerColumnType(Types.INTEGER, "integer");
registerColumnType(Types.BIGINT, "bigint");
registerColumnType(Types.FLOAT, "float");
registerColumnType(Types.REAL, "real");
registerColumnType(Types.DOUBLE, "double");
registerColumnType(Types.NUMERIC, "numeric");
registerColumnType(Types.DECIMAL, "decimal");
registerColumnType(Types.CHAR, "char");
registerColumnType(Types.VARCHAR, "varchar");
registerColumnType(Types.LONGVARCHAR, "longvarchar");
registerColumnType(Types.DATE, "date");
registerColumnType(Types.TIME, "time");
registerColumnType(Types.TIMESTAMP, "longvarchar");
registerColumnType(Types.TIMESTAMP, "datetime");
registerColumnType(Types.BINARY, "blob");
registerColumnType(Types.VARBINARY, "blob");
registerColumnType(Types.LONGVARBINARY, "blob");
// registerColumnType(Types.NULL, "null");
registerColumnType(Types.BLOB, "blob");
registerColumnType(Types.CLOB, "clob");
registerColumnType(Types.BOOLEAN, "integer");
registerColumnType(Types.NULL, "null");
registerHibernateType(Types.NULL, "null");
registerFunction("concat", new VarArgsSQLFunction(IntegerType.INSTANCE,
"", "||", ""));
registerFunction("mod", new SQLFunctionTemplate(IntegerType.INSTANCE,
"?1 % ?2"));
registerFunction("substr", new StandardSQLFunction("substr",
IntegerType.INSTANCE));
registerFunction("substring", new StandardSQLFunction("substr",
IntegerType.INSTANCE));
registerFunction("replace", new StandardSQLFunction("replace",
IntegerType.INSTANCE));
registerFunction("current_time", new NoArgSQLFunction(
"datetime('now')",
CalendarType.INSTANCE, false));
registerFunction("current_timestamp", new NoArgSQLFunction(
"strftime('%s','now')*1000", CalendarType.INSTANCE, false));
registerFunction("current_date", new NoArgSQLFunction(
"strftime('%s','now')*1000",
CalendarType.INSTANCE, false));
registerFunction(
"trunc",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%d-%m-%Y\", ?1/1000, 'unixepoch', 'localtime') as string)"));
registerFunction(
"second",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%S\", ?1/1000, 'unixepoch', 'localtime') as integer)"));
registerFunction(
"minute",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%M\", ?1/1000, 'unixepoch', 'localtime') as integer)"));
registerFunction(
"hour",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%H\", ?1/1000, 'unixepoch', 'localtime') as integer)"));
registerFunction(
"day",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%d\", ?1/1000, 'unixepoch', 'localtime') as integer)"));
registerFunction(
"month",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%m\", ?1/1000, 'unixepoch', 'localtime') as integer)"));
registerFunction(
"year",
new SQLFunctionTemplate(IntegerType.INSTANCE,
"cast (strftime(\"%Y\", ?1/1000, 'unixepoch', 'localtime') as integer)"));
registerFunction("trim", new AbstractAnsiTrimEmulationFunction() {
protected SQLFunction resolveBothSpaceTrimFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"trim(?1)");
}
protected SQLFunction resolveBothSpaceTrimFromFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"trim(?2)");
}
protected SQLFunction resolveLeadingSpaceTrimFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"ltrim(?1)");
}
protected SQLFunction resolveTrailingSpaceTrimFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"rtrim(?1)");
}
protected SQLFunction resolveBothTrimFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"trim(?1, ?2)");
}
protected SQLFunction resolveLeadingTrimFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"ltrim(?1, ?2)");
}
protected SQLFunction resolveTrailingTrimFunction() {
return new SQLFunctionTemplate(StandardBasicTypes.STRING,
"rtrim(?1, ?2)");
}
});
}
@Override
public boolean supportsIdentityColumns() {
return true;
}
/*
* public boolean supportsInsertSelectIdentity() { return true; // As
* specify in NHibernate dialect }
*/
@Override
public boolean hasDataTypeInIdentityColumn() {
return false; // As specify in NHibernate dialect
}
/*
* public String appendIdentitySelectToInsert(String insertString) { return
* new StringBuffer(insertString.length()+30). // As specify in NHibernate
* dialect append(insertString).
* append("; ").append(getIdentitySelectString()). toString(); }
*/
@Override
public String getIdentityColumnString() {
// return "integer primary key autoincrement";
return "integer";
}
@Override
public String getIdentitySelectString() {
return "select last_insert_rowid()";
}
@Override
public boolean supportsLimit() {
return true;
}
// Added fix from bug,
// http://code.google.com/p/hibernate-sqlite/issues/detail?id=1
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public String getLimitString(String query, boolean hasOffset) {
return new StringBuffer(query.length() + 20).append(query)
.append(hasOffset ? " limit ? offset ?" : " limit ?").toString();
}
@Override
public String getLimitString(final String s, final int min, final int max) {
String limitString = super.getLimitString(s, min, max);
return limitString;
}
@Override
public boolean supportsTemporaryTables() {
return true;
}
@Override
public String getCreateTemporaryTableString() {
return "create temporary table if not exists";
}
@Override
public boolean dropTemporaryTableAfterUse() {
return false;
}
@Override
public boolean supportsCurrentTimestampSelection() {
return true;
}
@Override
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
@Override
public String getCurrentTimestampSelectString() {
return "select current_timestamp";
}
@Override
public boolean supportsUnionAll() {
return true;
}
@Override
public boolean hasAlterTable() {
return false; // As specify in NHibernate dialect
}
@Override
public boolean dropConstraints() {
return false;
}
@Override
public String getAddColumnString() {
return "add column";
}
@Override
public String getForUpdateString() {
return "";
}
@Override
public boolean supportsOuterJoinForUpdate() {
return false;
}
@Override
public String getDropForeignKeyString() {
throw new UnsupportedOperationException(
"No drop foreign key syntax supported by SQLiteDialect");
}
@Override
public String
getAddForeignKeyConstraintString(String constraintName,
String[] foreignKey,
String referencedTable,
String[] primaryKey,
boolean referencesPrimaryKey) {
throw new UnsupportedOperationException(
"No add foreign key syntax supported by SQLiteDialect");
}
@Override
public String getAddPrimaryKeyConstraintString(String constraintName) {
throw new UnsupportedOperationException(
"No add primary key syntax supported by SQLiteDialect");
}
@Override
public boolean supportsIfExistsBeforeTableName() {
return true;
}
@Override
public boolean supportsIfExistsAfterTableName() {
return false;
}
@Override
public boolean supportsCascadeDelete() {
return false;
}
}
确保在构建 session 工厂之前设置“hibernate.dialect”属性:
private SessionFactory buildSessionFactory() throws Exception {
StandardServiceRegistryBuilder serviceRegistryBuilder =
new StandardServiceRegistryBuilder();
org.hibernate.cfg.Configuration config = new Configuration();
config.setProperty("hibernate.dialect", dialect);
//Any additional config options, or just set this in your hibernate xml config...
serviceRegistryBuilder.applySettings(config.getProperties());
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
sessionFactory = config.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
这是一个 smaller version I found for .NET
这应该可以解决您的问题。如果没有,您可以通过为 ORM 映射设置设置时间类型来使用其他解决方法:
[Temporal(TemporalType.TIMESTAMP)]
显然,TemporalTypes 在 csharp 中被称为 CustomTypes。 answers for this question 之一提供了一个示例.
此外,您可能需要 account for timezones .
关于c# - 在执行 ISQLQuery.UniqueResult<DateTime>() 时,如何让 SQLite 返回正确的 DateTime?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23630074/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!