Ok, so here's an enum, right?
public enum BrandSafe : short
{
Yes = 1,
No = -1,
Unknown = 0
}
Underlying datatype of short, OK, so far so good.
Here is a table:
Now, here is a DTO class:
public class VurlRow
{
public long VurlRMXID { get; set; }
public string VurlString { get; set; }
public Enums.BrandSafe BrandSafe { get; set; }
}
Finally, here is a linq method:
List<VurlRow> vurls = (from vurl in m_Context.Vurls
select new VurlRow()
{
BrandSafe = (Enums.BrandSafe)vurl.BrandSafe,
VurlRMXID = vurl.VurlRMXID,
VurlString = vurl.VurlString
}).ToList();
I've also tried (Enums.BrandSafe)Enum.ToObject(typeof(Enums.BrandSafe), vurl.BrandSafe) to produce the Enum. When I remove the line BrandSafe = (Enums.BrandSafe)vurl.BrandSafe, the call works, but with the line I get a InvalidCast exception.
"Specified cast is not valid."
Seems like it should be totally valid to me, but what do I know, not enough about enums and linq apparently, can anyone here help?
BrandSafe is tinyint in the database; tinyint maps to byte, not short. That's the problem. Make it:
public enum BrandSafe : byte
{
Yes = 1,
No = -1, // <====== see below
Unknown = 0
}
(short would map to smallint)
However!!!! Note that -1 is not really a legal value for either of byte/tinyint - it will be 255 or an OverflowException in .NET (depending on whether it is a checked or unchecked context), and an arithmetic-overflow (error 220) at the database.
I do, however, wonder whether bool? (in C#) and bit null (TSQL) would be a better match.
Related
I have seen two approaches to setting a property as nullable. What is the difference between the two approaches? which one is clean?
public string? a { get; set; };
public string b { get; set; } = default!;
Edit 1: Updated code to correct syntax and changed int -> string
You wrote int a?instead of int? a.
The 2 behave very differently here. An int is not nullable, its default value is 0. Therefore you can just use defuslt without the ! . The ! just makes the compiler ignore null check rules.
The other creates a real null value.
Lets say we instead had:
string? a = null
Or
string a = default!
Which behave almost the same, but their type differs.
In that case the ? nullable reference type is more clean as you dont get rid of the null safety guarantees.
The first approach is correct so to say.
You can understand this clearly using snippet as below.
void Main()
{
var pro = new Pro{
a = 1,
//b = 1
};
Console.WriteLine(typeof(int));
Console.WriteLine(typeof(int?));
}
public class Pro {
public int? a { get; set; }
public int b { get; set; } = default!;
}
I'm trying to get the difference between two dates, but I get this error:
Cannot Convert type 'int?' to 'System.TimeSpan'
Then I tried to use Convert.ToInt32() or Int32.Parse(), but still had the same error.
Can anyone please help me or point me in the right direction?
ViewModel:
public class RMACLOSE
{
public TimeSpan? diff { get; set; }
}
Controller:
var list = from RH in RMA_History
select new RMACLOSE
{
// Cannot Convert type 'int?' to 'System.TimeSpan?'
diff = DbFunctions.DiffDays(RH.EndDate, RH.StartDate)
}
RH.EndDate (DateTime): 2018-11-15 12:15:00.000
RH.StartDate (DateTime): 2018-05-24 15:43:00.000
Difference : 175 days
I think you need the difference between both date means EndDate and StartDate and i.e. 175,
So why you could not use int? type of diff property inside RMACLOSE class like
public class RMACLOSE
{
public int? diff { get; set; }
}
And might be your error becomes solved and then you don't need any type casting and you simply use your LINQ query as it is like
select new RMACLOSE
{
diff = DbFunctions.DiffDays(RH.EndDate, RH.StartDate)
}
DbFunctions.DiffDays returns int? so it matches your diff property type and then no error will remain.
It is evident from the error message that DbFunctions.DiffDays() returns an int? (that presumably represents the time difference in days).
Therefore you will need to do something like this to convert it into TimeSpan?:
var days = DbFunctions.DiffDays();
if (days != null)
diff = TimeSpan.FromDays(days.Value);
else
diff = null;
I am using tl-language compiler to compile schema of Telegram Api TL language described in https://core.telegram.org/mtproto in C#
There is a compiler that compile tl-language to C# classes https://github.com/everbytes/SharpTL.Compiler
But it can compile new telegram schema at this line:
"params":[
{"name":"flags","type":"#"},
{"name":"report_spam","type":"flags.0?true"}]
,"type":"PeerSettings"}
And it compile it to wrong code:
[TLObject(0x818426CD)]
public partial class PeerSettings : IPeerSettings
{
[TLProperty(1)]
public I# Flags { get; set; }
[TLProperty(2)]
public IFlags0?true ReportSpam { get; set; }
}
Is there any solution in casting in C# codes?
I do not know what is type of this "flags:#" in C#
This type "#" described in https://core.telegram.org/mtproto/TL-formal
user {flags:#} id:flags.0?string first_name:flags.1?string last_name:flags.2?string reserved3:flags.3?False reserved4:flags.4?False = User flags;
In the future, bits 3 and 4 in the flags field may be used to transmit new fields after changing the names and types of the reserved3 and reserved4 fields
this means int according to TLGenerator
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings
deep searching around this I think this hash (#) means that dynamic value of variable, in some cases it can be true or false, another cases it can be a sequence of integers nonnegative:
matrix {X:Type} m:# n:# a:(%Tuple (%Tuple X m) n) = Matrix X;
above we got the M and N taking a integer random value > 0
get_users req_fields:# ids:%(Vector int) = Vector %(User req_fields)
in this another case it can assume a conditional value
req_fields variable is cast only to User object, but in other cases it could be casted
to another kind of object.
maybe the correct way of this TLObject in c# is :
[TLObject(0x818426CD)]
public partial class PeerSettings : IPeerSettings
{
[TLProperty(1)]
public int Flags { get; set; }
[TLProperty(2)]
public bool ReportSpam { get; set; }
}
apologises my english is rusty
I want to merge, outer join the column "Count" from View_AssessmentCount list to View_Assessment. Of course Count will get an error because it is int and I wrote String.Empty. It's at this part where I specify where to outer join the null column "Count". But then again I don't know the right terms to Google this. Please help me expound on this.
public class AssessmentWithCount
{
public int Count { get; set; }
public String AssessmentName { get; set; }
public String AssessmentInitials { get; set; }
public Int16 id { get; set; }
}
public IEnumerable<AssessmentWithCount> GetAssessmentWithCount()
{
using (var context = new SQL_TA_SCOREBOARDEntities1())
{
var query = from a in context.View_Assessment
join b in context.View_AssessmentCount on a.AssessmentName equals b.AssessmentName into ab
from subA in ab.DefaultIfEmpty()
select new AssessmentWithCount
{
AssessmentName = a.AssessmentName,
Count = (subA == null ? String.Empty : subA.Count.ToString())
};
return query;
}
}
Updated post
Now my error is "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection." when I DataBind this class. :(
Don't convert the database field to a string - just use it as-is:
Count = (subA == null ? 0 : (subA.Count ?? 0))
Regarding the error message... the using statement disposes your instance of SQL_TA_SCOREBOARDEntities1, so you need to get your data now, before leaving the method:
return query.ToList();
Here try this instead:
Count = SubA.Count ?? 0
Just had some issues like these and got help. :)
Sorry I can't comment as I have less than 50 reps.
Am using EntityFramework and have a LinkStatusID column which is a tinyint, which gets generated into a byte in C#.
public enum LinkStatus
{
Added = 0,
Deleted = 1
}
however this gives:
a.LinkStatusID = (byte)Enums.LinkStatus.Deleted;
is there a more elegant way to structure this?
EDIT2 for LastCoder:
public enum LinkStatus : byte
{
Added = 0,
Deleted = 1
}
var blah = Enums.LinkStatus.Added;
var ty = blah.GetType();
var blah2 = (byte)Enums.LinkStatus.Added;
var ty2 = blah2.GetType();
This doesn't work (as I expected) however the first answer here explains why.
EDIT3:
EF isn't the only way this sln gets to the DB, so I'm keen to keep the Enums explicit in the code. Thanks for EF5 Enum suggestions!
public enum LinkStatus : byte
Will avoid the explicit cast.
You should probably use the native enum support, like SLaks mentioned above (Tutorial is here). If you don't want to do that, you can do something else that I found for before EF supported it:
public int CountryInt{get;set;}
public Countries Country
{
get { return (Countries) this.CountryInt; }
set { this.CountryInt = (int) value; }
}
Using this, then, allows you to just set the Country variable, and have it automatically go to the DB as the correct int value.
A static class can be used as a workaround
public static class LinkStatus
{
public static byte
Added = 0,
Deleted = 1;
}