How can I cast the result of an ExecuteScalar command to a GUID structure without first using .ToString() to pass to the constructor of the GUID?
The reason for doing this is performance and not creating thousands of unnecessary string objects in memory.
It is possible using a reader and the GetGUID Method but I can not see any references to how to achieve the same when using a scalar value.
Update: I also need to handle DBNull Values
Assuming that your sql statement cannot return DBNull.Value, then yes you can:
Guid myResult = (Guid) cmd.ExecuteScalar();
EDIT: Now that we know you need to handle nulls.... :-)
I can think of two ways to handle nulls - use a nullable Guid and set it to null, or use a regular Guid and have it set to Guid.Empty if your SQL statement returns null.
Consider some form of helper function or extension method which checks for DBNull.Value.
static Guid? GetGuidFromDb(object dbValue)
{
if (dbValue == null || DBNull.Value.Equals(dbValue))
{
return null;
}
else
{
return (Guid) dbValue;
}
}
or
static Guid GetGuidFromDb(object dbValue)
{
if (dbValue == null || DBNull.Value.Equals(dbValue))
{
return Guid.Empty;
}
else
{
return (Guid) dbValue;
}
Then call
Guid? myResult = GetGuidFromDb(cmd.ExecuteScalar());
Note - this will choke if your SQL command returns a datatype other than UniqueIdentifier.
If the object being returned from the command is a UniqueIdenitifier, then yes.
Guid myResult = cmd.ExecuteScalar() as Guid? ?? Guid.Empty;
Related
I have a linq query:
var capacityQuery = from Info in mySQLDataTable.AsEnumerable()
where Info.Field<object>("location") == Location.ID
orderby Info.Field<DateTime>("date")
The line "where Info.Field("location") == Location.ID" is where I am having problems
My Question is. How do I do a comparison in the where statement that might be either a DBNull.Value or an int value on either side
Below is for reference:
Location is a custom class. The ID returns an object.
private int? addressID;
public object ID {
get
{
if (addressID == null)
return DBNull.Value;
else
return addressID;
}
}
The reason it has to be DBNull is because it is coming from a database. The "table" is also being filled in from a database.
I know == in this case is wrong because its comparing the references which is obviously false.
I know object.equal(var1, var2) should work but it doesnt which im guessing is because they are 2 different objects.
The values could be an int or DBNull both on the table side and the class side.
This is in a foreach loop so I use the same query where Location has an int value or when it has a DBNull value.
Again My Question is. How do I do a comparison in the where statement that might be either a DBNull.Value or an int value on either side
Use
private int? addressID;
public object ID {
get
{
return addressID.HasValue ? addressID.Value as object : DBNull.Value;
}
}
instead. This way, if addressID has not been initialized or if it has been deliberately set to null, the ID property will return a DBNull.Value. Otherwise, it will return an int, but you have to cast it yourself from object to int or int?.
Having said that, creation of the null has been called "a billion dollar mistake" by the author, but by now I think it is in the trillions. You should return an int? datatype from the database if you can, in which case, the comparison will always work. I am not sure which ORM do you use, but Dapper and linq2db handle this scenario correctly as far as I know.
I am getting the error:
Input string was not in a correct format.
Some of the Parent Id's can be null. If I comment the ParentId it is successful, so I know it is that line.
var mModel = new MyModel
{
//non nullable
Id = int.Parse(dr["Id"].ToString()),
//nullable
ParentId = int.Parse(dr["ParentId"].ToString()), <--- Throwing the error here
//non nullable
ProductService = dr["MyString"].ToString()
};
I have tried Convert.ToInt32(), and TryParse() and event a ToNullableInt extension Method, but that didnt work.
Check for database null in the dr["ParentId"] and then convert to an int or assign null, like this:
ParentId = !dr.IsDBNull(dr.GetOrdinal("ParentId"))
? dr.GetInt32(dr.GetOrdinal("ParentId"))
: null;
Note: The above code assumes that the ParentId variable is a nullable integer (int? or Nullable<int>.
I don't like calling to string on datareader, moreover, it has methods to get data of specific type
Pattern is
if (!dr.IsDBNull(1)) s = dr.GetString(1)
Or for nullable int:
if (!dr.IsDBNull(1)) i = dr.GetInt32(1)
Note: if you know column name and don't know ordinal or vise-a-versa, you can use GetOrdinal and
GetName methods:
var i = dr.GetOrdinal("ParentId")
var name = dr.GetName(1)
You shouldn't use int.Parse on a value that will not parse correctly... it'll throw an exception.
If you're sure the value will be null or have a valid value, you could try this:
ParentId = String.IsNullOrEmpty(Convert.ToString(dr["ParentId"]))
? (int?)null
: int.Parse(dr["ParentId"].ToString());
You may also want to look into Int32.TryParse, which allows you to try parsing and take some alternative action if the parse fails:
int id;
if (Int32.TryParse(Convert.ToString(dr["ParentId"]), out id)
ParentId = id;
else
ParentId = 0; // the parse failed
Incidentally, I like using Convert.ToString() over .ToString() in most cases, as the former converts null to an empty string, while the latter throws an exception. Just something to consider - doesn't help in this case, as int.Parse("") will throw an exception anyway.
I'm always using LINQ so I forgot how to check value in stored procedure whether it equals to 'new guid()' in C# or not
Is this correct
where (#SearchCategory = '000000-0000-0000-0000' )
or what???
'000000-0000-0000-0000' is not a 'new guid'. It is the value that is returned by Guid.Empty
Why don't you just use parametrized queries, and pass Guid.Empty to the parameter as a value ?
in .NET Guid is a class and it has static method to create a new GUID
Guid.NewGuid(); // This will return new guid
Guid.Empty; // This will return the 000000.... type value which is a empty guid value
Guid.NewGuid() holds a different value each time you call it.
When checking if the value holds a 'empty' Guid (uniqueidentifier) use '00000000-0000-0000-0000-000000000000'
(thats 8-4-4-4-12 zero's)
I have a dataset of values, which I need to put into a textbox. However, there are some decimal and double type values in my dataset, so I need to cast them toString(). Furthermore, sometimes the dataset values are empty, so before casting toString() I need to check whether there is actually a value there or not.
This is sample line:
I need code that does something like this...
if(ds.Tables[0].Rows[0].Field<decimal>("IndexPrethodni") !=null or something){
Convert.ToString(ds.Tables[0].Rows[0].Field<decimal>("IndexPrethodni"));
}
I known decimal is not a nullable type. Is there any easy solution to achieve my desired result?
Personally, I'd wrap it like so:
var col = ds.Tables[0].Columns["IndexPrethodni"];
var row = ds.Tables[0].Rows[0];
if (!row.IsNull(col))
{
string s = row[col].ToString();
...
}
(the "via a column object" is the most direct (= fastest) indexer)
Try
if(ds.Tables[0].Rows[0]["IndexPrethodni"] != DBNull.Value)
You can also check the value using Convert.IsDBNull().
I normally use a method such like:
public T GetValue<T>(object source)
{
if (Convert.IsDBNull(source))
return default(T);
return (T)source;
}
E.g.
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
return GetValue<string>(reader["SomeColumn"]);
}
}
check for DBNull
if(ds.Tables[0].Rows[0].Field("IndexPrethodni") != DBNull.Value) {
//convert to string
}
TO use Convert.ToString you need not to check for null value, because if there will null then also it will not give any error and return blank..
You need to check the value isnt DBNull, so something like this would work
object columnValue = ds.Tables[0].Rows[0].Field<decimal>("IndexPrethodni");
if (object != System.DBNull.Value) Convert.ToString(columnValue);
Why don't you use the nullable type to check for a value?
if( ds.Tables[ 0 ].Rows[ 0 ].Field<decimal?>( "IndexPrethodni" ).HasValue )
{
Convert.ToString( ds.Tables[ 0 ].Rows[ 0 ].Field<decimal>( "IndexPrethodni" ) );
}
If we are checking for decimal value is null or not before converting to other type
decimal? d;
if (!d.HasValue)
{
//d is null
}
I have a SQL query which returns only one field - an ID of type INT.
And I have to use it as integer in C# code.
Which way is faster and uses less memory?
int id;
if(Int32.TryParse(command.ExecuteScalar().ToString(), out id))
{
// use id
}
or
int? id = (int?)command.ExecuteScalar();
if(id.HasValue)
{
// use id.Value
}
or
int? id = command.ExecuteScalar() as int?;
if(id.HasValue)
{
// use id.Value
}
The difference between the three performance wise is negligible. The bottleneck is moving the data from the DB to your app, not a trivial cast or method call.
I would go with:
int? id = (int?)command.ExecuteScalar();
if(id.HasValue)
{
// use id.Value
}
It fails earlier, if one day people change the command to return a string or a date, at least it will crash and you will have a chance to fix it.
I would also just go with a simple int cast IF I always expected the command to return a single result.
Note, I usually prefer returning an out param than doing the execute scalar, execute scalar feels fragile (the convention that the first column in the first row is a return value does not sit right for me).
If you expect the command to return null, you should keep in mind that database null (DBNull) is not the same as .NET null. So, conversion of DBNull to int? would fail.
I'd suggest the following:
object result = command.ExecuteScalar();
int? id = (int?)(!Convert.IsDBNull(result) ? result : null);
If none of the above works (especially for users who are battling with MySQL)
why don't you try the following?
int id = Convert.ToInt32(cmd.ExecuteScalar().ToString());
int Result = int.Parse(Command.ExecuteScalar().ToString());
will work in C#.
The latter. Convert.ToInt32() is also an option.
Use id.HasValue for maximum Nullable Type cool-factor!
if ((Int32)cmd.ExecuteScalar () ** 1) //en esta parece qu esta el error pero no lo veo
{
Response.Redirect("Default.aspx");
}
else
{
Response.Redirect("error.htm") ;
}