I am getting the error:
Failed to convert parameter value from
a Int64 to a Byte[].
Here is what I am doing...
I have a table in my database with the column:
sessionid | binary(32) | null
When I assign to it, I do this:
user.LastActivityDate = DateTime.Now;
user.SessionId = user.LastActivityDate.ToBinary();
SessionId is an inherited property from an interface:
long? SessionId { get; set; }
And here it is being accessed in my User class:
[SettingsAllowAnonymous(false), CustomProviderData("SessionId;string")]
public long? SessionId { get { return base["SessionId"] as long?; } set { base["SessionId"] = value; } }
In my custom profile provider, the following command assigns the value:
sqlCommand.Parameters.Add("sessionid", SqlDbType.Binary, 32).Value = settingsPropertyValue.PropertyValue;
When the "sqlCommand.ExecuteNonQuery()" command executes an update stored
procedure is executed with the parameter:
#sessionid binary(32)
And the result is the error:
"Failed to convert parameter value
from a Int64 to a Byte[]."
I have tried:
... = Convert.ToByte(settingsPropertyValue.PropertyValue);
... = Convert.ToInt64(settingsPropertyValue.PropertyValue);
Any ideas? Thanks.
SqlDbType.Binary is not correct (when you add the parameter) -- that's for extended binary data of arbitrary length. You want to just represent it as a 64-bit integer, which is SqlDbType.BigInt.
By the way, why are you doing this in the first place? SQL has a date-time type; you can just store it like that.
(You could go about it in the opposite, perverse way and instead convert the long to an eight-byte array and pass that, but there's no conceivable reason you would want to store it in that manner.)
ToBinary doesn't do what you think it does.
The DateTime.ToBinary method returns a long value, not a byte array.
What are you trying to do?
If you're trying to store the datetime, you should just use a DataTime column.
If you actually want a byte array, please provide more details.
Related
Our entire application has been using a long to store large number values.
Like so:
public class SomeClass
{
public long CardNumber { get; set; }
}
This is stored as a bigint in Microsoft SQL Server.
Now in order to account for a value larger than a long's max value I'm changing the datatype to a string and nvarchar in SQL Server (open to a better solution).
We don't seem to be doing much arithmetic with the value already across the application.
But we have code like this:
var someObj = new SomeClass();
someObj.CardNumber = 1234;
So I don't want to have to manually change it to
var someObj = new SomeClass();
someObj.CardNumber = 1234.ToString();
Across the application..
I was thinking of doing something like this..
public class SomeClass
{
private long cardnum;
public string CardNumber
{
get { return cardnum.ToString(); }
set { cardnum = ConvertToLong(value); }
}
}
but what if I then want to set the card number to a value larger than the long max value....as the convert to long would break in the setter
I'm a bit lost as to what I should do here ...
If 28 digits are enough, you could use a C# decimal. A SQL decimal has even a precision of 38 digits. C# long has only 18 digits ulong has 19.
An assignment like someObj.CardNumber = 1234; will continue to work without changes, as the int constant is automatically converted to decimal.
For numbers larger than Int32.MaxValue you must use a decimal constant with the decimal specifier m. someObj.CardNumber = 1234_5678_9012_3456_7890m;. You can also use decimal separators. They are not limited to blocks of 3.
Always encrypt sensitive data!
In SQL Server you could alter the BIGINT column to be of type NUMERIC. The maximum integer length available is NUMERIC(38, 0). One way to store NUMERIC(38, 0) in memory using C# would be to use the (native SQL Server type) SqlDecimal which is implemented as a Struct in System.Data.SqlTypes.
I have an list of object which is have string "Value1" property and it is actually double.
So, I just want to get maximum and minimum values from my list with converting the property double.
That is my class.
public class Function
{
public int Id { get; set; }
public string Value1 { get; set; }
public string Value2 { get; set; }
}
I have a List<Function> and I need to get minimum "value1". Btw I am pretty sure about value1 can convertible to double. Is it possible to do this action in one line ?
What about simple casting?
myList.Max(x => double.Parse(x.Value1));
if you indeed want the min and the max, and you are sure the strings are all doubles:
string[] values = new[] { "1.1", "1.5", "2.654987" };
var doubles = values.Select(Convert.ToDouble);
var min = doubles.Min();
var max = doubles.Max();
LINQ can make it look nice
var sum = list.Select(item => item.Value1).Select(double.Parse).Sum();
You can pass a double.Parse function as parameter to the Select.
Notice that double.Parse will throw exception if Value1 is not valid double
It does matter whether you run your statement against database or not. if you do so and you do in one connection, so you will need to make all values in the same length as 'string' via a 'Select' statement and 'SqlFunctions.Replicate', and then 'Max' is going to work; but if your value contains decimals you will have trouble. Another way to escape from this solution is to fetch all value into memory using 'ToList' for instance; after that cast 'string' value to 'double' to get 'Max' statement working. but the downside is that all values is fetched into memory once
A SQL Server Timestamp becomes a byte[] in a POCO object. The object gets serialized and the timestamp becomes a base 64 string.
An example is 'AAAAAAA2QDE='
When the object is posted back to the server, during Model Validation you get:
The value 'AAAAAAA2QDE=' is not valid for Byte.
I am using this value to check the state of the record to compare to the current record in SQL to see if someone else has updated it since this user has retrieved it (pretty normal).
But the string is not deserializing back to a byte array, it appears that it is trying to put it into a single byte.
This should be a very common issue. Any ideas?
We can map the SQL Column (via ORM like NHibernate...) or directly with ADO.NET to property of type byte[], but make this property protected/internal to the server. Instead this, we can have another string property doing conversion as needed:
protected virtual byte[] Timestamp { get; set; }
public virtual string Version
{
get { return Timestamp.IsEmpty() ? null : Convert.ToBase64String(Timestamp); }
set { Timestamp = value.IsEmpty() ? null : Convert.FromBase64String(value); }
}
The Timestamp is for internal processing, representing the real bytes, the Version is for a Client ... is well de/serialized.
An example with NHibernate here
I read values from an local Access mdb-file. One value is stored as string in the db and I have it in a table. When using the GetType() method it return "System.String" and I can print it on the console without a problem but when I want to use it as an attribute for another method (requires a string) I get an error ("Cannot convert from 'object' to 'string'" and the same for 'int'). The same problems occur with some int values.
Am I doing something wrong or what is the problem in that case?
Console.WriteLine(dt.Rows[0][ProjName]); //prints project_name
Console.WriteLine(dt.Rows[0][ProjName].GetType()); //print "System.String"
Project = new Project(dt.Rows[0][ProjName], dt.Rows[0][MinDay], dt.Rows[0][MinWeek], dt.Rows[0][DayWeek]); //Error
Project = new Project(Convert.ToString(dt.Rows[0][ProjName]), Convert.ToInt32(dt.Rows[0][MinDay]), Convert.ToInt32(dt.Rows[0][MinWeek]), Convert.ToInt32(dt.Rows[0][DayWeek])); //Works Fine
Constructor for the Project Class:
public Project(string projectName, int hoursPerDay, int hoursPerWeek, int daysPerWeek)
You have stated in your answer is works when converting, and it is necessary as they are not strings and integers. They are objects. You can create a methid to handle it if you want.
public Project CreateProject(object projectName, object hoursPerDay, object hoursPerWeek, object daysPerWeek)
{
return new Project(projectName.ToString(), Convert.ToInt32(hoursPerDay), Convert.ToInt32(hoursPerWeek), Convert.ToInt32(daysPerWeek);
}
You have to explicitly cast the objects:
To cast to string use:
Object.ToString();
To cast to integers use:
Int32.TryParse(String, out int);
Your constuctor becomes
Project = new Project(dt.Rows[0][ProjName].ToString(), Int32.Parse(dt.Rows[0][MinDay]), Int32.Parse(dt.Rows[0][MinWeek]), Int32.Parse(dt.Rows[0][DayWeek]));
Note: Using Int32.Parse instead of Int32.TryParse assumes that the argument provided is a valid int at all times and does not give you a way to check if the casting has succeeded.
dt.Rows[0][ProjName] returns type object, and your method expects string. Even though you know it to be a string, it is not obvious to the compiler and must be specified explicitly using a cast, as you show in your last example, although just casting should be more efficient than converting unnecessarily:
Project = new Project((string)dt.Rows[0][ProjName], ...
I have a DetailsView, I need get the value specifield in DataKeyNames "UserId" (a Guid Field) and add it to an Object Guid.
At the moment I am using this code:
String myUserId = (String)uxAuthorListDetailsView.DataKey["UserId"].ToString();
but I would need something like:
Guid myUserGuid = (Guid)uxAuthorListDetailsView.DataKey["UserId"].ToString();
But does not work I get error Error
Cannot convert type 'string' to 'System.Guid'
What could be the problem? Thanks guys for your support!
Well, the problem is that you're calling ToString() and then trying to cast that string to a Guid, when there's no such conversion available. Possible alternatives:
Cast instead of calling ToString(), if the original value is really a Guid:
Guid guid = (Guid)uxAuthorListDetailsView.DataKey["UserId"];
Parse the string instead:
Guid guid = new Guid(uxAuthorListDetailsView.DataKey["UserId"].ToString());
If this is user-entered data at all, or there's any other reason why the value is half-expected to be incorrect, and if you're using .NET 4, you might want to use Guid.TryParse instead, which will allow you to handle failure without an exception.
var myUserGuid = new Guid(uxAuthorListDetailsView.DataKey["UserId"].ToString());
Check under debug: what object is uxAuthorListDetailsView.DataKey["UserId"]
I guess this must be already the Guid; and conversion is not needed
Assuming uxAuthorListDetailsView.DataKey["UserId"] stores a valid Guid
try this
Guid myUserGuid = (Guid)uxAuthorListDetailsView.DataKey["UserId"]
remove ToString method