开发者

Why do I need to cast these returned results?

开发者 https://www.devze.com 2023-02-18 05:48 出处:网络
// Insert new record ArtworkingDataContext dc = new ArtworkingDataContext(); tblArtworkData NewRecord = new tblArtworkData()
    // Insert new record
    ArtworkingDataContext dc = new ArtworkingDataContext();
    tblArtworkData NewRecord = new tblArtworkData()
    {
        dateCreated = DateTime.Now,
        templateID = TemplatesID,
        userID = UsersID
    };
    dc.tblArtworkDatas.InsertOnSubmit(NewRecord);

    // Set new values
    this.Loaded = true;
    this.ID = NewRecord.ID;
    this.DateCreated = (DateTime)NewRecord.dateCreated;
    this.TemplateID = (int)NewRecord.templateID;
    this.UserID = (int)NewRecord.userID;
}

When I set the new 开发者_如何学Pythonvalues, ID doesn't need casting, but the others do, otherwise I get:

Cannot implicitly convert type 'int?' to 'int'.

I'm getting bored already of casting all my returned data, what am I doing wrong? And why doesn't the ID need a cast?


Apart from all the other answers here - this could indicate a bigger issue in the DB design an Linq to Sql Mapping.

Your object clearly expects these values to be provided all the time; but the database columns must be nullable. If the data going in the table will never be null, then you should make them NOT NULL and then set the 'Nullable' property in the designer for each of the properties to 'false'

Then you'll no longer need either a cast nor a .HasValue check.

Equally, instead of these you can do:

Value = nullable ?? default_Value;

Where default_Value is some kind of sentinel integer - e.g. -1 or 0


You don't need to cast int? to int, but rather, just use .Value on the object (or, rather, the GetValueOrDefault() extension method if that is safer for you). The error is just complaining that you are passing a nullable type to a property that is not nullable.


It seems NewRecord.templateID and NewRecord.userID are of type Nullable<int> or int? in C#.

A wrapper class that enables an Int32, in this case, to be null.

The ID field is probably set as 'not null' in the database. Look at your DB schema, templateID and userID possibly allow nulls, which get translated to Nullable<T> types.

Nullable Structure


what am I doing wrong?

If the values in the data record are of type int?, and the object that you're populating has properties of type int, then the first thing you're doing wrong is casting. And not because writing (int) all the time is boring. This:

this.UserID = (int)NewRecord.userID;

is going to throw a InvalidOperationException when NewRecord.userID contains null. There, now what was boring has become exciting in a way you didn't want.

There are two possible responses to this:

  1. "But that will never happen." In that case, fix whatever is creating NewRecord so that its properties aren't nullable. You'll probably find that yes, actually it can happen, because the underlying column in the database is nullable.

  2. "OK, since the database column is nullable, I guess it can happen." In this case, you need to find out why the column is nullable. If the user ID contains NULL, what does this mean, and what should your application be doing when it is? You will probably find that you need to make your local object's properties int? instead of int, and then include logic that handles the case where their value is null.

A lot of people have suggested that you use the null coalescing operator or some other way of assigning a default value. Sometimes that's a good idea - if you know what the null value is supposed to mean. But the idea of using ?? to assign a sentinel value isn't really solving the problem, it's changing what is already a perfectly serviceable sentinel value - null - into a value that only works if it can't naturally occur in the value space. Sometimes you have to do this - if, for instance, you're talking to some piece of code that doesn't support null values - but it's something you should do very reluctantly.


you have to check if the nullable values do have a value.

int x;
int? nullable;

if(nullable.HasValue)
   x = nullable;

the reason is that int != int?

int? is just a short form for

Nullable<int>


I guess that these fields are Nullable in the database.

Since the data could be null then the C# maps these to Nullable data fields - e.g. int? (which is shorthand for Nullable<int>)

Instead of casting them, you should probably check for null using .HasValue and then use the .Value property - or you could use the null coalescence operator - ??

If you want to avoid this conversion, then the only way I can think of is to change your database so that these fields can't be null (and also possibly to provide a default value for them)


Your ID field isn't Nullable in the database - so it's represented by and int and not a int? in your C#

Hope that helps

Stuart


You need something like this.DateCreated = NewRecord.dateCreated.GetValueOrDefault();


I don't think this is related to Linq. The compiler is telling you that there is no implicit cast between a Nullable<T> and T. Obviously, for normal values, the cast is easy. But it doesn't know what to do if dateCreated is null


TemplateID and UserID are not int they're System.Nullable<int> and that is why you have to cast them. Either make this.TemplateId and This.UserID Nullable<int> or use the .Value property on Nullable objects.

0

精彩评论

暂无评论...
验证码 换一张
取 消