.NET: How to change the value in a DataTable - data-binding

In ADO.NET i'm using GetSchemaTable to return the schema table for a results set.
DataTable schema = rdr.GetSchemaTable();
gridSchema.DataSource = schema;
gridSchema.DataBind();
Unfortunatly the "ProviderType" value is displaying as an integer, rather than the OleDbType enumeration value that it is:
ProviderType Desired Display Value
============ =====================
129 Char
3 Integer
129 Char
129 Char
3 Integer
3 Integer
129 Char
135 DBTimeStamp
129 Char
129 Char
...
All these integers are the the enumeration values for the OleDbType enumeration:
public enum OleDbType
{
Empty = 0,
SmallInt = 2,
Integer = 3,
Single = 4,
Double = 5,
Currency = 6,
Date = 7,
BSTR = 8,
IDispatch = 9,
Error = 10,
Boolean = 11,
Variant = 12,
IUnknown = 13,
Decimal = 14,
TinyInt = 16,
UnsignedTinyInt = 17,
UnsignedSmallInt = 18,
UnsignedInt = 19,
BigInt = 20,
UnsignedBigInt = 21,
Filetime = 64,
Guid = 72,
Binary = 128,
Char = 129,
WChar = 130,
Numeric = 131,
DBDate = 133,
DBTime = 134,
DBTimeStamp = 135,
PropVariant = 138,
VarNumeric = 139,
VarChar = 200,
LongVarChar = 201,
VarWChar = 202,
LongVarWChar = 203,
VarBinary = 204,
LongVarBinary = 205,
}
i want to display the data type as something human readable, rather than an integer.
i've tried looping through the schema DataTable and modify the values inside the DataTable:
DataTable schema = rdr.GetSchemaTable();
//Change providerType column to be readable
foreach (DataRow row in schema.Rows)
{
OleDbType t = (OleDbType)row["ProviderType"];
row["ProviderType"] = t.ToString();
}
gridSchema.DataSource = schema;
gridSchema.DataBind();
But that throws an exception:
Column 'ProviderType' is read only.
i even looked at the GridView's RowDataBound event, thinking i could change the value as it is rendered:
protected void gridSchema_RowDataBound(object sender, GridViewRowEventArgs e)
{
//todo: magic
//e.Row["ProviderType"]
}
But it doesn't look like you can play with rendered values.
Can anyone suggest a nice way to much with the value of the ProviderType column so that it is human readable when i display it to humans?
Update
The workaround i'm using right now is tack an extra column on the end:
DataTable schema = rdr.GetSchemaTable();
schema.Columns.Add("OleDbDataType", typeof(String));
schema.Columns.Add("CLRDataType", typeof(String));
foreach (DataRow row in schema.Rows)
{
//Show the actual provider type
OleDbType t = (OleDbType)row["ProviderType"];
row["OleDbDataType"] = t.ToString();
//Show the corresponding CLR type while we're doing a hack
row["CLRDataType"] = row["DataType"].ToString();
}
gridSchema.DataSource = schema;
gridSchema.DataBind();

I might be completely off here, but can't you just set the ReadOnly property of the column to false? Like:
schema.Columns["ProviderType"].ReadOnly = false;
Afterwards you might get a columntype problem as you're trying to put a string value into a integer column. But this should get you into the right direction.
edit:
Solving the columntype issue:
DataTable newTable = schema.Clone();
newTable.Columns["ProviderType"].DataType = typeof(string);
foreach (DataRow dr in schema.Rows)
{
DataRow newRow = newTable.NewRow();
// fill newRow with correct data and newly formatted providertype
newTable.Rows.Add(newRow);
}

Or you could create an object with all the fields from the datatable, pass all the data into your object and modify it or create a read only field that returns the string acording to the integer given.
GridView and other also accept object arrays as datasources so it is automatic.

Related

(Godot Engine) How do I know which exported enum flags are enabled in script

By using the Godot engine and writing in the GDScript language,
let's say I have an enum declared as:
enum eTextMode {CHAR, NUMBER, SYMBOLS_TEXT, SYMBOLS_ALL}
And an export variable as:
export(eTextMode, FLAGS) var _id: int = 0
In the inspector panel I can see which flag is selected or not, but how can I know in code which specifically flag is selected?
By selecting in the inspector, for example: the NUMBER and SYMBOLS_TEXT flags, the _id variable will be set as 5
My approach is the following hard-coded dictionary:
var _selected_flags: Dictionary = {
CHAR = _id in [1, 3, 5, 7, 9, 11, 13, 15],
NUMBER = _id in [2, 3, 6, 7, 10, 11, 14, 15],
SYMBOLS_TEXT = _id in [4, 5, 6, 7, 12, 13, 14, 15],
SYMBOLS_ALL = _id in [8, 9, 10, 11, 12, 13, 14, 15]
}
Resulting in:
{CHAR:True, NUMBER:False, SYMBOLS_ALL:False, SYMBOLS_TEXT:True}
The above result is exactly what I'm expecting (a dictionary with string keys as they are defined in the enum with a boolean value representing the selection state).
How could I manage to do this dynamically for any enum regardless of size?
Thank you very much,
One tacky solution that I could manage is by not using an enum at all, but instead a dictionary like the following example:
const dTextMode: Dictionary = {CHAR = false, NUMBER = false, SYMBOLS_TEXT = false, SYMBOLS_ALL = false}
export(Dictionary) var m_dTextMode: Dictionary = dTextMode setget Set_TextMode, Get_TextMode
func Get_TextMode() -> Dictionary: return m_dTextMode
func Set_TextMode(_data: Dictionary = m_dTextMode) -> void: m_dTextMode = _data
An exported dictionary is not as good-looking as an exported enum with FLAGS, and by following this approach it kind of invalidates my initial problem.
By selecting CHAR and SYMBOLS_TEXT in the exported dictionary from the inspector, and then calling print(self.Get_TextMode()) the result is indeed what I expected:
{CHAR:True, NUMBER:False, SYMBOLS_ALL:False, SYMBOLS_TEXT:True}
I still can't figure out though how to achieve this result by using the export(*enum, FLAGS) aproach.
Edit: also, the setter function is not feasible to be used in script since the user must know to duplicate the dTextMode constant first, edit it and set is as an argument.
Thanks to the comments from #Thearot from my first answer, I have managed to figure out the following solution which meets all expectations, with one caveat: it seems like an overkill solution...
enum eTestFlags {FLAG_1, FLAG_2, FLAG_3, FLAG_5, FLAG_6}
export(eTestFlags, FLAGS) var m_iTestFlags: int = 0 setget Set_TestFlags
func Get_TestFlags() -> Dictionary: return self._get_enum_flags(m_iTestFlags, eTestFlags)
func Set_TestFlags(_id: int = m_iTestFlags) -> void: m_iTestFlags = _id
func _get_enum_flags(_val_selected: int, _enum: Dictionary, _bit_check_limit: int = 32) -> Dictionary:
var _enum_keys: Array = _enum.keys() ; _enum_keys.invert()
var _bin_string: String = ""
var _val_temp: int = 0
var _val_count: int = _bit_check_limit - int(_is_pow2(_bit_check_limit))
while(_val_count >= 0):
_val_temp = _val_selected >> _val_count
_bin_string += "1" if _val_temp & 1 else "0"
_val_count -= 1
var _bin_string_padded: String = "%0*d" % [_enum_keys.size(), int(_bin_string)]
var _result_dict: Dictionary = {}
for _str_id in range(_bin_string_padded.length(), 0, -1):
_result_dict[_enum_keys[_str_id - 1]] = bool(_bin_string_padded[_str_id - 1] == "1")
return _result_dict
func _is_pow2(_value: int) -> bool:
return _value && (not (_value & (_value - 1)))
Now, if I print(self.Get_TestFlags()) after selecting FLAG_2 and FLAG_6 the result is:
{FLAG_1:False, FLAG_2:True, FLAG_3:False, FLAG_5:False, FLAG_6:True}
You're on the right track but overcomplicating things. Without going too much into the math (see Wikipedia), here's what you'd do in Godot:
enum eTextMode {CHAR, NUMBER, SYMBOLS_TEXT, SYMBOLS_ALL}
export(eTextMode, FLAGS) var _id: int = 0
func _ready() -> void:
for modeName in eTextMode:
var bit_flag_value: int = int(pow(2, eTextMode[modeName]))
if _id & bit_flag_value:
printt("Flagged", modeName)
You can access the named fields of your enum like elements in an Array/Dictionary by default (iterate through the keys, get their 0-based index as values). The above math trick turns the 0-based index into the correct bit flag number, and if you (single) '&' it with the combined bit-flags value you can check whether or not that flag is set.

parsing integer array on JSONcpp

I'm having trouble parsing integer arrays using JsonCpp.
I am trying to read an array of integers from json input.
I'm getting the error:
ambiguous overload for 'operator[]' in 'dataArray[0]'
I've tried:
Json::Value c_val;
const Json::Value dataArray = root["data"];
c_val = dataArray[0]; int a = c_val.asInt();
c_val = dataArray[1]; int b = c_val.asInt();
and I've also tried
int a = dataArray[0];
To no avail. Sample input json file:
{
"data" : [ 1047, 140, 60, 60 ]
}
For future reference:
Force integer input with '0u':
c_val = dataArray[0u]; int a = c_val.asInt();
solves it.

Encountered "ORA-01745: invalid host/bind variable name" when using DbDataAdapter.Update() with ODP.NET

I have a table defined in oracle 11g with below statement:
CREATE TABLE "TESTUSER"."TestTableOracleWriter"
("name" VARCHAR2(100 BYTE),
"group" VARCHAR2(100 BYTE),
"number" NUMBER(*,0),
"creation" DATE,
"sliceidentifier" RAW(100),
CONSTRAINT "TESTTABLEORACLEWRITER_PK" PRIMARY KEY ("name"))
And I am using the following code snippet to update the table with content in the dataTable:
private void BatchInsert(DbConnection connection, DbTransaction transaction, DataTable dataTable, string tableName)
{
DbDataAdapter adapter = ProviderFactories.GetFactory("Oracle.DataAccess.Client").CreateDataAdapter();
DbCommand insertCommand = connection.CreateCommand();
DbParameter parameter1 = insertCommand.CreateParameter();
parameter.DbType = DbType.String;
parameter.ParameterName = "#name";
parameter.SourceColumn = "name";
insertCommand.Parameters.Add(parameter);
DbParameter parameter2 = insertCommand.CreateParameter();
parameter2.DbType = DbType.String;
parameter2.ParameterName = "#group";
parameter2.SourceColumn = "group";
insertCommand.Parameters.Add(parameter2);
DbParameter parameter3 = insertCommand.CreateParameter();
parameter3.DbType = DbType.Int32;
parameter3.ParameterName = "#number";
parameter3.SourceColumn = "number";
insertCommand.Parameters.Add(parameter3);
DbParameter parameter4 = insertCommand.CreateParameter();
parameter4.DbType = DbType.DateTime;
parameter4.ParameterName = "#creation";
parameter4.SourceColumn = "creation";
insertCommand.Parameters.Add(parameter4);
insertCommand.CommandType = CommandType.Text;
insertCommand.CommandText = "INSERT INTO \"TestTableOracleWriter\" (\"name\", \"group\", \"number\", \"creation\") VALUES (:name, :group, :number, :creation)";
insertCommand.Transaction = transaction;
insertCommand.UpdatedRowSource = UpdateRowSource.None;
adapter.InsertCommand = insertCommand;
adapter.UpdateBatchSize = 0;
adapter.Update(dataTable);
}
But sometimes the code will fail with "ORA-01745: invalid host/bind variable name", I've searched on the internet and found some materials saying it has something to do with the oracle reserve word. From the link, "name", "group" and "number" is marked as reserve word. I can change my table column names to make the code work.
But the strangest thing is that the code does not fail all the time, it only fails when dataTable cotains only one row, in other scenarios, it works as expected. Anyone has ideas about that?
You can not use key word as parameter name.
Don't use group and number as parameter name

Getting error while inserting table in database?

i am inserting table in database using table datatype with the following code:
CREATE TYPE BackUpDoctorLocationAreaRoom AS TABLE (
[RoomId] bigint,
[AreaId] bigint,
[LocationId] bigint
);
Alter proc proc_tblBackUpDoctorInsert
(
#Id uniqueidentifier='',
#BackUpDoctorId uniqueidentifier='1323e1f4-7a93-4b45-9a9b-3840c32fd6d8',
#StartDate datetime='11/08/2012',
#EndDate datetime='11/09/2012',
#StartTime datetime='22:22:22',
#EndTime datetime='01:11:11',
#CreatedBy uniqueidentifier='acf7961c-4111-49ad-a66a-ce7f9ce131bd',
#ModifiedBy uniqueidentifier='acf7961c-4111-49ad-a66a-ce7f9ce131bd',
#createdDate datetime='11/6/12 3:09:58 AM',
#ModifiedDate datetime='11/6/12 3:09:58 AM',
#tblBackUpDoctorsForRooms BackUpDoctorLocationAreaRoom READONLY
)
as
set xact_abort on
declare #newId uniqueidentifier;
set #newId = newid();
insert into tblBackUpDoctor (Id,BackUpDoctorId,StartDate,EndDate,StartTime,EndTime,CreatedBy,ModifiedBy,
createdDate,ModifiedDate,IsActive,isdeleted) values
(#newId,
#BackUpDoctorId,
#StartDate,
#EndDate,
#StartTime,
#EndTime,
#CreatedBy,
#ModifiedBy,
#createdDate,
#ModifiedDate,
1,0)
declare #IdFortblBackUpDoctorsForRooms uniqueidentifier;
set #IdFortblBackUpDoctorsForRooms = newid();
delete from tblBackUpDoctorsForRooms where BackUpRecordId=#id and Roomid in (Select roomid from #tblBackUpDoctorsForRooms)
delete from tblbackupdoctor where id=#id
insert into tblBackUpDoctorsForRooms (BackUpRecordId,Roomid,Araeid,locationid)
Select #newId,roomid,areaid,locationid from #tblBackUpDoctorsForRooms
select #newId
This is the sp in which i am using that table.
My class file's code is :
public string InsertBackUpDoctor(ClsBackUpDoctorProp objProp, DataTable dtLocAreaRoom)
{
String ConnectionString = CCMMUtility.GetCacheForWholeApplication();
String backUpRecordId = "";
SqlParameter[] param = new SqlParameter[12];
param[0] = new SqlParameter("#Id", objProp.Id);
param[1] = new SqlParameter("#BackUpDoctorId", objProp.BackUpDoctorId);
param[2] = new SqlParameter("#StartDate", objProp.StartDate);
param[3] = new SqlParameter("#EndDate", objProp.EndDate);
param[4] = new SqlParameter("#StartTime", objProp.StartTime);
param[5] = new SqlParameter("#EndTime", objProp.EndTime);
param[6] = new SqlParameter("#CreatedBy", objProp.CreatedBy);
param[7] = new SqlParameter("#ModifiedBy", objProp.ModifiedBy);
param[8] = new SqlParameter("#createdDate", CCMMUtility.GetCurrentDateTimeByTimeZone("US Mountain Standard Time"));
param[9] = new SqlParameter("#ModifiedDate", CCMMUtility.GetCurrentDateTimeByTimeZone("US Mountain Standard Time"));
param[10] = new SqlParameter("#CurrentDate", objProp.CurrentDate);
param[11] = new SqlParameter("#tblBackUpDoctorsForRooms ", dtLocAreaRoom);
backUpRecordId = SqlHelper.ExecuteScalar(ConnectionString, "proc_tblbackupdoctorInsertBackUpDoctors", param).ToString();
return backUpRecordId;
}
and here is the error which is coming when i tries to insert :
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Table-valued parameter 12 ("#tblBackUpDoctorsForRooms"), row 0, column 0: Data type 0xF3 (user-defined table type) has a non-zero length database name specified. Database name is not allowed with a table-valued parameter, only schema name and type name are valid.
I dont know why this coming please help me..
I believe you'd have to change the way you pass your custom parameter:
Not just
param[11] = new SqlParameter("#tblBackUpDoctorsForRooms ", dtLocAreaRoom);
but rather something like
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#tblBackUpDoctorsForRooms";
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "BackUpDoctorLocationAreaRoom";
parameter.Value = dtLocAreaRoom;
param[11] = parameter;
try
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "BackUpDoctorLocationAreaRoom";
and in the call add
backUpRecordId = SqlHelper.ExecuteScalar(ConnectionString,CommandType.StoredProcedure
"proc_tblbackupdoctorInsertBackUpDoctors", param).ToString();

Entity Framework and Linq - Comparing DateTime

I have this code
public List<CalendarData> GetCalendarData(DateTime day)
{
List<CalendarData> list = new List<CalendarData>();
using (dataContext = new VTCEntities())
{
DateTime test = new DateTime(2010, 10, 20, 17, 45, 0);
var data = from z in dataContext.ReservationsSet
where z.start_time.Value == test
select z;
foreach (var r in data)
What I'd like to do is have this
var data = from z in dataContext.ReservationsSet
where z.start_time.Value == day
select z;
the problem I have is that z.start_time has the time part also. The DateTime day doesn't have the time part recorded. Is there a way to compare the the date part of without getting this error
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
when I do this
var data = from z in dataContext.ReservationsSet
where z.start_time.Value.Date == test
select z;
One option is to compute two values, like this:
DateTime day = ...;
DateTime nextDay = day.AddDays(1);
var data = from z in dataContext.ReservationsSet
where z.start_time.Value >= day &&
z.start_time.Value < nextDay
select z;
You can't use .Date in Entity Framework. The easiest way I know to handle this is to make a minimum + maximum day:
DateTime test = new DateTime(2010, 10, 20, 17, 45, 0);
DateTime startDay = test.Date;
DateTime endDay = startDay.AddDays(1);
var data = from z in dataContext.ReservationsSet
where z.start_time.Value >= startDay && z.start_time.Value < endDay
select z;

Resources