I have people telling me that I should set up objects for my tables, but I
am finding the Null problem makes that difficult.
It isn't a big problem if you are not updating the table, but if you are -
it is a real problem if you have Nullable fields. You can't always use a 0
or -1 to tell whether a field is null and dates are another problem. I
don't want to use some obscure date in the future for something like
"EndDate" or "DateTerminated" where there is no ending date or an employee
hasn't been terminated yet.
You don't have a problem if you use a field on an asp.net screen, as an
empty field would be taken as null. But that is not the same in an object
where you have to define a value for your fields.
I can see some real advantages to using objects for my tables, but they seem
to be outweighed by being unable to handle the nulls in either vb.net or c#.
I'd be curious to know how others are handling this problem (without using 0
or 1 or obscure data).
The problem is not reading the data from the table, but when changes are
made and you need to write it back, you need to know when a field is
supposed to be Null.
Thanks,
Tom 14 1883
"tshad" <ts**********@ftsolutions.com> wrote in message
news:ea**************@TK2MSFTNGP10.phx.gbl... You don't have a problem if you use a field on an asp.net screen, as an empty field would be taken as null. But that is not the same in an object where you have to define a value for your fields.
You do?
I can see some real advantages to using objects for my tables, but they
seem to be outweighed by being unable to handle the nulls in either vb.net or
c#. I'd be curious to know how others are handling this problem (without using
0 or 1 or obscure data).
The problem is not reading the data from the table, but when changes are made and you need to write it back, you need to know when a field is supposed to be Null.
I take it you are using simple data types for the "fields" on your objects.
If that's what you really want to do, you can define each private field as
"object" then cast it in the getter/setter. I don't know how big the
performance penalty is for "boxing" all those values, it'll certainly depend
on your application. We use objects to hold various information about our
"fields". We find it advantagous to be able to hold more information than
just the current value - for example the "old" value (as loaded from the
database), whether the field is loaded or not (some fields are lazy loaded),
and whether the field is null, among other things.
So, our code looks like this (method names reveal my Delphi background):
myObject.FirstName.AsString = "Scott";
myObject.LastName.AsString = "Roberts";
myObject.Salary.AsFloat = 250000.00; // haha!
I could also do:
myObject.Salary.AsString = SalaryEdit.Text; // conversion handled by
"AsString", handles "$", etc.
myObject.Salary.IsNull = true;
Just some ideas. Don't think that you're limited to:
private decimal _salary;
public decimal Salary
{
get {return _salary;}
set {_salary = value;}
}
"Scott Roberts" <sc***********@no-spam.intelebill.com> wrote in message
news:ea**************@TK2MSFTNGP14.phx.gbl... "tshad" <ts**********@ftsolutions.com> wrote in message news:ea**************@TK2MSFTNGP10.phx.gbl...
You don't have a problem if you use a field on an asp.net screen, as an empty field would be taken as null. But that is not the same in an object where you have to define a value for your fields. You do?
Actually, what I do is check for null coming from the database or check to
see if my field (textbox or label) is blank if going to the database.
For non-strings (int, decimal, money, dates) this is how I have to handle
it.
If the data coming from the database is Null, I leave the field blank. Then
when I write the data back and the field is blank, I send DBNull.Value like
so:
if salaryDesired.text = ""
.Add("@salaryDesired",SqlDbType.Money).value = DBNull.Value
else
.Add("@salaryDesired",SqlDbType.Money).value =
Regex.Replace(salaryDesired.text,"\$|\,","")
end if
I can't do that in an object as there is now in intermediate step.
I get the data from the database, put the data into the Objects private
variables (which can't be null). I then do whatever I am going to do on the
page and would now need to move the data back to the Object (again can't be
null) and then the data is moved from the Objects private variables to the
database record.
How do you tell if a value was a Null when you put it back? I can see some real advantages to using objects for my tables, but they seem to be outweighed by being unable to handle the nulls in either vb.net or c#. I'd be curious to know how others are handling this problem (without using
0 or 1 or obscure data).
The problem is not reading the data from the table, but when changes are made and you need to write it back, you need to know when a field is supposed to be Null.
I take it you are using simple data types for the "fields" on your objects. If that's what you really want to do, you can define each private field as "object" then cast it in the getter/setter. I don't know how big the performance penalty is for "boxing" all those values, it'll certainly depend on your application. We use objects to hold various information about our "fields". We find it advantagous to be able to hold more information than just the current value - for example the "old" value (as loaded from the database), whether the field is loaded or not (some fields are lazy loaded), and whether the field is null, among other things.
Keeping the old value would obviously be valuable. But do you do that for
all your fields?
For example, I have about 150 fields in one of my table records (mixture of
strings, ints, money and bits).
Do you set up each field as an object? So, our code looks like this (method names reveal my Delphi background):
myObject.FirstName.AsString = "Scott"; myObject.LastName.AsString = "Roberts"; myObject.Salary.AsFloat = 250000.00; // haha!
Wouldn't that be nice. :)
I would do the same thing if I were setting up an object where the class
might be Position.
Then I would access my private variables as:
Position.FirstName = "Joe";
Position.Salary = 320000.00; // Thinking a little higher.
My class might be something like:
**********************************************
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using MyFunctions;
namespace FtsData
{
[Serializable]
public class Position
{
private int positionID = 0;
private string firstName = "";
private decimal Salary = 0;
public Position()
{
}
public Position(int PositionID)
{
}
public int AddRecord()
{
int rowsAffected = 0;
int iError = 0;
DbObject myDbObject = new DbObject();
SqlParameter[] parameters = {
new SqlParameter("@PositionID",SqlDbType.Int),
new SqlParameter("@FirstName",SqlDbType.VarChar,30),
new SqlParameter("@Salary",SqlDbType.Money) };
parameters[0].Value = positionID;
parameters[1].Value = firstName;
parameters[2].Value = salary;
try
{
iError = myDbObject.RunProcedure("AddPosition", parameters, ref
rowsAffected);
}
catch (SqlException sqle)
{
throw sqle;
}
}
// Properties
public int PositionID
{
get { return positionID; }
set { positionID = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public decimal Salary
{
get { return salary; }
set { salary = value; }
}
}
}
************************************************** *********************
Thanks,
Tom I could also do:
myObject.Salary.AsString = SalaryEdit.Text; // conversion handled by "AsString", handles "$", etc. myObject.Salary.IsNull = true;
Just some ideas. Don't think that you're limited to:
private decimal _salary; public decimal Salary { get {return _salary;} set {_salary = value;} }
i wrote a "NullHandler" class. By design, i decided for Value Types (int,
decimal, DataTime etc.) MaxValue indicates DBNull, for reference types, null
indicates DBNull.. when i get/set a value from/to database object
(DataReader, DataParameter etc.) i use NullHandler.. only boolean type cant
be null in my design. (because i didnt need. i hope you wont need too.)
here is the class.
using System;
namespace DataAccess
{
public sealed class NullHandler
{
private NullHandler()
{
}
public static void GetValueFromDbObject(object dbObjectValue, ref string
destination)
{
destination = dbObjectValue == DBNull.Value ? null : (string)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref int
destination)
{
destination = dbObjectValue == DBNull.Value ? int.MaxValue :
(int)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref decimal
destination)
{
destination = dbObjectValue == DBNull.Value ? decimal.MaxValue :
(decimal)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref DateTime
destination)
{
destination = dbObjectValue == DBNull.Value ? DateTime.MaxValue :
(DateTime)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref long
destination)
{
destination = dbObjectValue == DBNull.Value ? long.MaxValue :
(long)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref byte
destination)
{
destination = dbObjectValue == DBNull.Value ? byte.MaxValue :
(byte)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref object
destination, Type destinationType)
{
switch(destinationType.Name)
{
case "System.String" :
destination = dbObjectValue == DBNull.Value ? null : dbObjectValue;
break;
case "System.Int32" :
destination = dbObjectValue == DBNull.Value ? Int32.MaxValue :
dbObjectValue;
break;
case "System.Decimal" :
destination = dbObjectValue == DBNull.Value ? Decimal.MaxValue :
dbObjectValue;
break;
case "System.DateTime" :
destination = dbObjectValue == DBNull.Value ? DateTime.MaxValue :
dbObjectValue;
break;
case "System.Int64" :
destination = dbObjectValue == DBNull.Value ? Int64.MaxValue :
dbObjectValue;
break;
case "System.Byte" :
destination = dbObjectValue == DBNull.Value ? Byte.MaxValue : dbObjectValue;
break;
default :
if(destinationType.IsValueType)
throw new NotImplementedException("Converting from type '" +
dbObjectValue.GetType().Name + "' to '" + destinationType.Name + "' not
implemented..");
destination = dbObjectValue == DBNull.Value ? null : dbObjectValue;
break;
}
}
public static void SetDbObjectValueFromValue(string sourceValue, ref object
dbObjectValue)
{
if(sourceValue == null)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(int sourceValue, ref object
dbObjectValue)
{
if(sourceValue == int.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(decimal sourceValue, ref object
dbObjectValue)
{
if(sourceValue == decimal.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(DateTime sourceValue, ref
object dbObjectValue)
{
if(sourceValue == DateTime.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(long sourceValue, ref object
dbObjectValue)
{
if(sourceValue == long.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(byte sourceValue, ref object
dbObjectValue)
{
if(sourceValue == byte.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(object sourceValue, Type
sourceValueType, ref object dbObjectValue)
{
switch(sourceValueType.Name)
{
case "System.String" :
{
string val = (string)sourceValue;
if(val == null)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Int32" :
{
int val = (int)sourceValue;
if(val == int.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Decimal" :
{
decimal val = (decimal)sourceValue;
if(val == decimal.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.DateTime" :
{
DateTime val = (DateTime)sourceValue;
if(val == DateTime.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Int64" :
{
long val = (long)sourceValue;
if(val == long.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Byte" :
{
byte val = (byte)sourceValue;
if(val == byte.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
default :
if(sourceValueType.IsValueType)
throw new NotImplementedException("Converting from type '" +
dbObjectValue.GetType().Name + "' to '" + sourceValueType.Name + "' not
implemented.");
if(sourceValue == null)
dbObjectValue = DBNull.Value;
else
sourceValue = sourceValue;
break;
} // End Switch Statment
} // End Method Block
}
}
Here is how i use this class :
protected override void DoLoad(IDataReader rd)
{
this.itemName = (string)rd["ItemName"];
NullHandler.GetValueFromDbObject(rd["Description"], ref this.description);
NullHandler.GetValueFromDbObject(rd["ItemGroupId"], ref this.itemGroupId);
}
protected override void AppendSaveParameters(DbParameterCollection paramCol)
{
paramCol.Add(
DataAccessHelper.ParameterHandler.GetInputParamete rFromValue("ItemName",
itemName) );
paramCol.Add(
DataAccessHelper.ParameterHandler.GetInputParamete rFromValue("Description",
description) );
paramCol.Add(
DataAccessHelper.ParameterHandler.GetInputParamete rFromValue("ItemGroupId",
itemGroupId) );
}
DataAccessHelper's ParameterHandler property is a kind of factory -
singleton (DataAccessHelper instantinates a specific ParameterHandler based
on "DataProvider" value in the application settings. (for example it
instantinates SqlParameterHandler class written by me.), and returns this
single instance everytime a parameter handler is requested.) here is a
method of SqlParameterHandler :
IDataParameter
DataAccess.Interfaces.IDbParameterHandler.GetInput ParameterFromValue(string
paramName, byte value)
{
IDataParameter param = new SqlParameter("@" + paramName, SqlDbType.TinyInt);
object obj = null;
NullHandler.SetDbObjectValueFromValue(value, ref obj);
param.Value = obj;
return param;
}
Hope this helps.. you can ask further.
"tshad" <ts**********@ftsolutions.com> wrote in message
news:OO**************@tk2msftngp13.phx.gbl... "Scott Roberts" <sc***********@no-spam.intelebill.com> wrote in message news:ea**************@TK2MSFTNGP14.phx.gbl...
if salaryDesired.text = "" .Add("@salaryDesired",SqlDbType.Money).value = DBNull.Value else .Add("@salaryDesired",SqlDbType.Money).value = Regex.Replace(salaryDesired.text,"\$|\,","") end if
I can't do that in an object as there is now in intermediate step.
Sure you can. It's the GUI's responsibility to set the business object
properties correctly. It's the BO's responsibility to persist the data
correctly.
if salaryDesired.Text = string.Empty
myObject.salaryDesired.IsNull = true;
else
myObject.salaryDesired.AsString = salaryDesired.Text;
I get the data from the database, put the data into the Objects private variables (which can't be null).
Sure they can, if they are of type "object".
Keeping the old value would obviously be valuable. But do you do that for all your fields?
Yes. It's how I know if a particular field needs to be persisted to the
database or not. I don't write fields to the DB that didn't change.
For example, I have about 150 fields in one of my table records (mixture
of strings, ints, money and bits).
So? Are you writing an application for devices with limited memory? If so,
that makes a difference.
Do you set up each field as an object?
Yes.
> So? Are you writing an application for devices with limited memory? If so, that makes a difference.
how about if you are writing a multi-client app like a web app? then it
makes difference.
and one thing about keeping old values : do you use dynamic sql? if not, how
do you send parameters (only changed fields)
This looks good. I assume this is similar to what Scott was talking about.
2 questions.
1. I have never used the Object type. Is it defined somewhere or is it
like a variant type that contains any type of data? I assumed that was the
case as you move any type of data into it.
2. How would you handle data that happened to be the Max Value of that
particular type?
For example, I assume that the MaxValue for byte is 255. I can see that
hitting the max value for decimal or long would be rare, but I can
definately see using 255 for a byte.
Thanks,
Tom
"The Crow" <q> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl... i wrote a "NullHandler" class. By design, i decided for Value Types (int, decimal, DataTime etc.) MaxValue indicates DBNull, for reference types, null indicates DBNull.. when i get/set a value from/to database object (DataReader, DataParameter etc.) i use NullHandler.. only boolean type cant be null in my design. (because i didnt need. i hope you wont need too.) here is the class.
using System;
namespace DataAccess
{
public sealed class NullHandler
{
private NullHandler()
{
}
public static void GetValueFromDbObject(object dbObjectValue, ref string destination)
{
destination = dbObjectValue == DBNull.Value ? null : (string)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref int destination)
{
destination = dbObjectValue == DBNull.Value ? int.MaxValue : (int)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref decimal destination)
{
destination = dbObjectValue == DBNull.Value ? decimal.MaxValue : (decimal)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref DateTime destination)
{
destination = dbObjectValue == DBNull.Value ? DateTime.MaxValue : (DateTime)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref long destination)
{
destination = dbObjectValue == DBNull.Value ? long.MaxValue : (long)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref byte destination)
{
destination = dbObjectValue == DBNull.Value ? byte.MaxValue : (byte)dbObjectValue;
}
public static void GetValueFromDbObject(object dbObjectValue, ref object destination, Type destinationType)
{
switch(destinationType.Name)
{
case "System.String" :
destination = dbObjectValue == DBNull.Value ? null : dbObjectValue;
break;
case "System.Int32" :
destination = dbObjectValue == DBNull.Value ? Int32.MaxValue : dbObjectValue;
break;
case "System.Decimal" :
destination = dbObjectValue == DBNull.Value ? Decimal.MaxValue : dbObjectValue;
break;
case "System.DateTime" :
destination = dbObjectValue == DBNull.Value ? DateTime.MaxValue : dbObjectValue;
break;
case "System.Int64" :
destination = dbObjectValue == DBNull.Value ? Int64.MaxValue : dbObjectValue;
break;
case "System.Byte" :
destination = dbObjectValue == DBNull.Value ? Byte.MaxValue : dbObjectValue;
break;
default :
if(destinationType.IsValueType)
throw new NotImplementedException("Converting from type '" + dbObjectValue.GetType().Name + "' to '" + destinationType.Name + "' not implemented..");
destination = dbObjectValue == DBNull.Value ? null : dbObjectValue;
break;
}
}
public static void SetDbObjectValueFromValue(string sourceValue, ref object dbObjectValue)
{
if(sourceValue == null)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(int sourceValue, ref object dbObjectValue)
{
if(sourceValue == int.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(decimal sourceValue, ref object dbObjectValue)
{
if(sourceValue == decimal.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(DateTime sourceValue, ref object dbObjectValue)
{
if(sourceValue == DateTime.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(long sourceValue, ref object dbObjectValue)
{
if(sourceValue == long.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(byte sourceValue, ref object dbObjectValue)
{
if(sourceValue == byte.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue;
}
public static void SetDbObjectValueFromValue(object sourceValue, Type sourceValueType, ref object dbObjectValue)
{
switch(sourceValueType.Name)
{
case "System.String" :
{
string val = (string)sourceValue;
if(val == null)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Int32" :
{
int val = (int)sourceValue;
if(val == int.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Decimal" :
{
decimal val = (decimal)sourceValue;
if(val == decimal.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.DateTime" :
{
DateTime val = (DateTime)sourceValue;
if(val == DateTime.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Int64" :
{
long val = (long)sourceValue;
if(val == long.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
case "System.Byte" :
{
byte val = (byte)sourceValue;
if(val == byte.MaxValue)
dbObjectValue = DBNull.Value;
else
dbObjectValue = val;
break;
}
default :
if(sourceValueType.IsValueType)
throw new NotImplementedException("Converting from type '" + dbObjectValue.GetType().Name + "' to '" + sourceValueType.Name + "' not implemented.");
if(sourceValue == null)
dbObjectValue = DBNull.Value;
else
sourceValue = sourceValue;
break;
} // End Switch Statment
} // End Method Block }
}
Here is how i use this class : protected override void DoLoad(IDataReader rd)
{
this.itemName = (string)rd["ItemName"];
NullHandler.GetValueFromDbObject(rd["Description"], ref this.description);
NullHandler.GetValueFromDbObject(rd["ItemGroupId"], ref this.itemGroupId);
}
protected override void AppendSaveParameters(DbParameterCollection paramCol)
{
paramCol.Add( DataAccessHelper.ParameterHandler.GetInputParamete rFromValue("ItemName", itemName) );
paramCol.Add( DataAccessHelper.ParameterHandler.GetInputParamete rFromValue("Description", description) );
paramCol.Add( DataAccessHelper.ParameterHandler.GetInputParamete rFromValue("ItemGroupId", itemGroupId) );
} DataAccessHelper's ParameterHandler property is a kind of factory - singleton (DataAccessHelper instantinates a specific ParameterHandler based on "DataProvider" value in the application settings. (for example it instantinates SqlParameterHandler class written by me.), and returns this single instance everytime a parameter handler is requested.) here is a method of SqlParameterHandler : IDataParameter DataAccess.Interfaces.IDbParameterHandler.GetInput ParameterFromValue(string paramName, byte value)
{
IDataParameter param = new SqlParameter("@" + paramName, SqlDbType.TinyInt);
object obj = null;
NullHandler.SetDbObjectValueFromValue(value, ref obj);
param.Value = obj;
return param;
}
Hope this helps.. you can ask further.
> This looks good. I assume this is similar to what Scott was talking about.
2 questions.
1. I have never used the Object type. Is it defined somewhere or is it like a variant type that contains any type of data? I assumed that was the case as you move any type of data into it.
actually, i didnt ever used object type overload. i wrote it just for case,
when i didnt wrote an overload for a type. but in my project, i didnt needed
that method yet.
2. How would you handle data that happened to be the Max Value of that particular type?
For example, I assume that the MaxValue for byte is 255. I can see that hitting the max value for decimal or long would be rare, but I can definately see using 255 for a byte.
this made me think too, but i didnt needed the value "255" for any byte
field too. but if i would need, it shows byte data type is not big enough
for that data, because when i werent used null handler and byte type, after
using 255, 256 wont be possible too. so think 254 is your limit for byte,
rather then 255. but if there is a real deal (for example you have to deal a
value that comes from a part of computer system), you can choose not using
NullHandler for that particular field and acces it directly.
"The Crow" <q> wrote in message
news:OB**************@TK2MSFTNGP12.phx.gbl... and one thing about keeping old values : do you use dynamic sql? if not,
how do you send parameters (only changed fields)
Yes, dynamic sql
do you think its good? did u measure performance?
"The Crow" <q> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl... do you think its good? did u measure performance?
I assume you are referring to the ability of most DBs to cache execution
plans and reuse them if the same SQL statment is issued multiple times.
There are trade-offs to every decision. We are aware of the above fact
(applies to SQL Server and Oracle for sure) and decided to go with dynamic
SQL anyway. The advantages we see are:
1. Concurrency ("last save wins" is sufficient for us if only changed fields
are saved).
2. Less DB access (no SQL generated at all if no fields changed, regardless
of how many times the user clicks "Save")
3. Smaller SQL commands (if only 1 of 150 fields changed, the SQL generated
is very small).
4. For batch operations, it's always the same field(s) changing so the same
3 or 4 SQL statments will be dynamically generated and statement caching is
effective.
"tshad" <ts**********@ftsolutions.com> wrote in message
news:OO**************@tk2msftngp13.phx.gbl... "Scott Roberts" <sc***********@no-spam.intelebill.com> wrote in message news:ea**************@TK2MSFTNGP14.phx.gbl... I take it you are using simple data types for the "fields" on your objects. If that's what you really want to do, you can define each private field as "object" then cast it in the getter/setter. I don't know how big the performance penalty is for "boxing" all those values, it'll certainly depend on your application. We use objects to hold various information about our "fields". We find it advantagous to be able to hold more information than just the current value - for example the "old" value (as loaded from the database), whether the field is loaded or not (some fields are lazy loaded), and whether the field is null, among other things.
I am looking at the Crow's class and like how it's done.
But that one also uses a one dimensioned simple variant type of data to hold
the value.
How would you change my class to have old values and a field to hold whether
it is null or not?
Would you set it up a multidimension variable or as a complex type of
object/structure?
I am just trying to look at different possibilities before going too much
farther with my objects if there is (and I am sure there is) a better way to
handle it and then have to reprogram it later.
Thanks,
Tom My class might be something like: ********************************************** using System; using System.Data; using System.Data.SqlClient; using System.Configuration; using MyFunctions;
namespace FtsData { [Serializable] public class Position { private int positionID = 0; private string firstName = ""; private decimal Salary = 0;
public Position() { }
public Position(int PositionID) {
}
public int AddRecord() { int rowsAffected = 0; int iError = 0; DbObject myDbObject = new DbObject(); SqlParameter[] parameters = { new SqlParameter("@PositionID",SqlDbType.Int), new SqlParameter("@FirstName",SqlDbType.VarChar,30), new SqlParameter("@Salary",SqlDbType.Money) };
parameters[0].Value = positionID; parameters[1].Value = firstName; parameters[2].Value = salary;
try { iError = myDbObject.RunProcedure("AddPosition", parameters, ref rowsAffected); } catch (SqlException sqle) { throw sqle; } }
// Properties
public int PositionID { get { return positionID; } set { positionID = value; } }
public string FirstName { get { return firstName; } set { firstName = value; } }
public decimal Salary { get { return salary; } set { salary = value; } } } } ************************************************** *********************
Thanks,
Tom I could also do:
myObject.Salary.AsString = SalaryEdit.Text; // conversion handled by "AsString", handles "$", etc. myObject.Salary.IsNull = true;
Just some ideas. Don't think that you're limited to:
private decimal _salary; public decimal Salary { get {return _salary;} set {_salary = value;} }
thanks for your answer. it seems to be wise.
"tshad" <ts**********@ftsolutions.com> wrote in message
news:%2******************@TK2MSFTNGP09.phx.gbl... How would you change my class to have old values and a field to hold
whether it is null or not?
Would you set it up a multidimension variable or as a complex type of object/structure?
Basically, we have a SBSFieldList class (just a wrapper around ArrayList
with some convenience methods) that holds a list of "SBSField" objects (or
objects derived from SBSField - e.g. SBSStringField).
public class MyClass
{
MyFieldListClass _fields = new MyFieldListClass();
public MyClass()
{
// Fill _fields with field objects.
}
public SBSStringField FirstName
{
get {return _fields.FieldByName("firstname");}
}
}
And you access the property like this:
myObject.FirstName.AsString = "Scott";
myObject.FirstName.IsNull = true; // Set the first name to null value.
Note: We don't actually do "FieldByName" and scan the list for the proper
field object every time you access a property, that would be slow. There are
integer array indexes stored for each property to speed things up, but this
is simpler for demo purposes. And you'd really want the field list defined
in a base class and populated by the derived classes. This allows the base
class to have access to the fields without the need for reflection, etc.
Still a little confused on what you are doing.
But it is probably a little more that I can do at the moment.
Thanks,
Tom
"Scott Roberts" <sc***********@no-spam.intelebill.com> wrote in message
news:uG**************@TK2MSFTNGP12.phx.gbl... "tshad" <ts**********@ftsolutions.com> wrote in message news:%2******************@TK2MSFTNGP09.phx.gbl...
How would you change my class to have old values and a field to hold whether it is null or not?
Would you set it up a multidimension variable or as a complex type of object/structure?
Basically, we have a SBSFieldList class (just a wrapper around ArrayList with some convenience methods) that holds a list of "SBSField" objects (or objects derived from SBSField - e.g. SBSStringField).
public class MyClass { MyFieldListClass _fields = new MyFieldListClass();
public MyClass() { // Fill _fields with field objects. }
public SBSStringField FirstName { get {return _fields.FieldByName("firstname");} } }
And you access the property like this:
myObject.FirstName.AsString = "Scott"; myObject.FirstName.IsNull = true; // Set the first name to null value.
Note: We don't actually do "FieldByName" and scan the list for the proper field object every time you access a property, that would be slow. There are integer array indexes stored for each property to speed things up, but this is simpler for demo purposes. And you'd really want the field list defined in a base class and populated by the derived classes. This allows the base class to have access to the fields without the need for reflection, etc.
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Thomas Coleman |
last post by:
I have been playing around with 2.0 and I'm trying clarify a few things about
generics and data access. I was hoping to be able to do something like this with
nullable types:
int? foo = null;
...
|
by: Raziq Shekha |
last post by:
Hello everyone,
SQL Server 2000. I have a database in which there are several objects
which have ansi nuls and quoted identifier turned ON. Is there a way I
can generate a script which:
(1)...
|
by: Robert Stearns |
last post by:
Either I missed something, or ALTER TABLE does not have this
capability. Is there any way of doing it except
DROPping all constraints which mention this table,
EXPORTing the data,
DROPping the...
|
by: jt |
last post by:
I can't seem to find a way to concatenate strings that have nulls within the
string.
I have a string that I need another string that has nulls in it and what to
append
the 2nd string, 3 string...
|
by: Simon |
last post by:
Hi all,
Do you think the best way to avoid the problems of nulls in the database is
just to provide default values via the db schema?
Alternatively, is it better to allow nulls, seeing as the...
|
by: Woody Splawn |
last post by:
I have some code that looks like this:
Dim SSN, LName, FName, M As String
mySqlConnection = New SqlConnection(myConnectionString)
Dim sql_Command As New SqlCommand( _
"Select SSN, LName, FName,...
|
by: Brian Henry |
last post by:
first question... I have a flat file which unfortinuatly has columns
seperated by nulls instead of spaces (a higher up company created it this
way for us) is there anyway to do a readline with this...
|
by: dmac |
last post by:
Hi, Im real new at this so be gentle. I want to create a customer
object based on the results of an sql query to the customers table, ie
one object per row, and then add each of these objects to an...
|
by: markjerz |
last post by:
Hi,
I basically have two tables with the same structure. One is an archive
of the other (backup). I want to essentially insert the data in to the
other.
I use:
INSERT INTO table ( column,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |