views:

390

answers:

4

Trying to set a Binary field to null gives me an ArgumentNull exception. I can set the field to be empty like this new Binary(new byte[] {}); but that's not null just an empty column. Is there a workaround using LinqToSql ?

A: 

You could use the ExecuteQuery() method to pass your own SQL.

Nate Bross
+1  A: 

Are you sure that the field is nullable in the database? Are the linq data model updated accordingly? If using attribute-based mapping there should be a CanBeNull=true setting in the [Column(...)] attribute.

Anders Abel
Good point, also if it wasn't defined as a nullable column when you added the table to the Linq2SQL designer, you'll need to delete the table from the designer and 're-add' it to have the updated schema changes.
Nate Bross
Yes good point, the column was nullable though
Karsten
+2  A: 

You've got something else going on. I just created a small sample table with an id (identity), nullable varbinary(MAX), non-nullable varbinary(MAX), and timestamp. Using the following code works just fine with no errors.

using (var context = new TestDataContext())
{
    var binarySample = new BinarySample
    {
        Image = null,
        NonNullImage = new Binary( new byte[0] ),
    };
    context.BinarySamples.InsertOnSubmit( binarySample );
    context.SubmitChanges();
}

Where as this code properly throws (and catches) a SQLException, not an ArgumentNullException.

try
{
    using (var context = new TestDataContext())
    {
        var binarySample2 = new BinarySample
        {
            NonNullImage = null,
            Image = new Binary( new byte[0] )
        };
        context.BinarySamples.InsertOnSubmit( binarySample2 );
        context.SubmitChanges();
    }
}
catch (SqlException e)
{
    Console.WriteLine( e.Message );
}

Is it possible that you have a partial class implementation that has a SendPropertyChanging handler for the property that is throwing the ArgumentNullException?

EDIT: based on the OP's comment.

Note that you can't assign a variable of type byte[] to the Binary directly as that invokes the implicit conversion operation and the implicit conversion will throw an ArgumentNullException. You should check if the value is null before attempting to assign it and simply assign null if the byte[] variable is null. To me this seems like odd behavior and I would hope that they would change it in the future. The MSDN documentation indicates that some change may occur in future versions.

tvanfosson
I posted my comment as an answer to get better formatting of the code, see below
Karsten
A: 

@tvanfosson (posted as an answer to get better formatting of the code)

Yes you are right, something strange is going on, something beyond my C# knowledge.

from.ImageThumbnail is byte[] to.ImageThumbnail is Binary

Using the ? or ?? operators won't work, if I just use if else it works, weird. I don't see why :-)

            if (from.ImageThumbnail != null) // works
            {
                to.ImageThumbnail = from.ImageThumbnail;
            }
            else
            {
                to.ImageThumbnail = null;
            }

            to.ImageThumbnail = from.ImageThumbnail != null ? from.ImageThumbnail : null; // fails

            to.ImageThumbnail = from.ImageThumbnail ?? null; // fails
Karsten
There is an implicit conversion operator from byte[] to Binary (http://msdn.microsoft.com/en-us/library/system.data.linq.binary.op_implicit.aspx) which handles the assignment. The conversion operation throws an exception in the case where the argument is null. This is actually noted in the documentation for the operator. Stick with the first version of the code.
tvanfosson
FYI -- you should probably edit your question and add this information there, rather that in a separate answer. This will make your question more useful to others looking for a solution to the same problem.
tvanfosson
I see, thanks for the info
Karsten