c# - Actualice las columnas de iSeries DATE/TIME/TIMESTAMP de.Net
orm entity-framework-4 (1)
Tengo una aplicación .Net usando EF4 y DB2 LUW e iSeries.
Cuando ejecutamos un comando en el DB2, clonamos el comando original en un nuevo iDB2Command, copiamos los parámetros y lo ejecutamos. Todo funciona muy bien, hasta que llegamos a las columnas de DATE
. En ese momento, parece que el AS400 o el controlador se caen: obtiene un parámetro que dice que es un DbTypes.DateTime
y contiene un objeto DateTime, pero la columna es DATE
.
El error devuelto (en LUW) está debajo. El AS400 (v6r1m0) devuelve una redacción ligeramente diferente
ERROR [22008] [IBM] CLI0114E Datetime field overflow. SQLSTATE=22008
El código se ve así (y es totalmente independiente de iSeries / DB2-LUW)
// all generic System.Data classes, no iDB2Connection datatype. The driver isn''t even
// installed on dev/build machines at this point. We rely on .Net reading the connection
// string from App.config to create the proper DB Driver (db2-luw or iSeries)
DbConnection c = ... get connection from somewhere...
DbCommand cmd = c.CreateCommand();
var p = cmd.CreateParameter();
p.ParamterName = "V_XXX_XXX";
p.DbType = DbTypes.DateTime;
p.Value = DateTime.Now;
cmd.AddParamter(p);
...
Asi que...
¿Hay algo que estamos haciendo mal aquí? Para LUW enviar el parámetro como un EDITAR: Funcionó muy bien en LUW porque estábamos enviando una fecha truncada en el código de prueba local (por ejemplo, DbTypes.DateTime
funciona bien.Now.Date
). Normal DateTime.Now
falla con un error de truncamiento como en el AS400)
Además, tenemos metadatos completos sobre el tipo, por lo que, en teoría, es posible decir, en el momento de la conversión, a qué System.DbTypes
convertir. Esperamos que eso sea todo lo que se necesita hacer (o cosas hacky de convertir a cuerdas), en lugar de un problema subyacente.
** Solución **
Gracias a @ mike-willis, solo revisamos la columna antes de crear el comando y realizamos un truncamiento manual cuando es necesario.
// get the db2 column type from our model metadata, because in .net it is all just DateTime
cmd.AddParamter("@MyDateColumn", FixParam( dateObject, metatdata.ColumnType);
// fix up different types of parameters. real version does a lot more validation
public object FixParam(object value, string db2columnType) {
if (db2columnType == "date") return ((DateTime)value).Date;
...
return value;
}
Gracias, todos ustedes, gente de DB2.
Viniendo del i, puede asignar desde un campo DATE
a un campo DATE
y DateTime
.
DateTime EmployeeSignedDateTime = i.Field<DateTime>("EMP_SIGNED_DATE").Add(i.Field<DateTime>("EMP_SIGNED_TIME").TimeOfDay)
Para enviarlo al i, puede hacer lo siguiente:
p.Add("@EMPLOYEE_SIGNED_DATE", iDB2DbType.iDB2Date).Value = DateTime.Now.Date;
p.Add("@EMPLOYEE_SIGNED_TIME", iDB2DbType.iDB2Time).Value = DateTime.Now.ToString("HH.mm.ss");
Tenga en cuenta que estoy usando IBM.Data.DB2.iSeries.dll
.