C# EF Core converting object to string / get; set - c#

I do get a stack overflow when trying to convert an object to a string in C#. I'm making an API Call to an endpoint and pass the response to this class. As the ef core does not support the datatype “object” I'm trying to convert this datatype to string to store it in the database as a column.
I have a class with various attributes like
public DateTime? start_date_local { get; set; }
public string? timezone { get; set; }
public double? utc_offset { get; set; }
some of them are from type object:
[NotMapped]
public object? start_latlng { get; set; }
As this datatype is not supported, I'm not mapping this to the DB, but I'm trying to convert this into a string and store it within a second datatype which can be inserted into the DB.
public string start_latlng2
{
get { return start_latlng2; }
set { start_latlng2 = Convert.ToString(start_latlng); }
}
This does not seem to work as I always get an error like:
Stack overflow.
Repeat 19126 times:
--------------------------------
at SportAnalytics.DataModel.Activity.get_start_latlng2()
--------------------------------
at DynamicClass.lambda_method171(System.Runtime.CompilerServices.Closure, Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.EnsureOriginalValues()
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntrySubscriber.SnapshotAndSubscribe(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry)
Am I doing something wrong? Is there a better way to achieve what I'm trying to do?

The StackoverflowException comes from the wrong definition of your property. You should write it with an explicit back field.
private string _start_latlng2;
public string start_latlng2
{
get { return _start_latlng2; }
set { _start_latlng2 = value; }
}
In your case you should use an explicit read-only property, that will be called when needed:
public string start_latlng2
{
get { return start_latlng == null ? null : Convert.ToString(start_latlng); }
}

You can try like this
public class Test{
public Test1 start_latlng {get;set;}
}
public class Test1{
public string Attr1 {get;set}
public string Attr2 {get;set}
}

#Oliver
sorry for asking once again a silly questions, but I just got started with C# a few weeks back.
I have now set something like this:
[NotMapped]
public object? start_latlng { get; set; } // was object
private string? _start_latlng2;
public string? start_latlng2
{
get { return start_latlng == null ? null : Convert.ToString(start_latlng); }
set { _start_latlng2 = value; }
}
If I run the debugger once again, I can see that the original object is an array like ["49,11", "49,12"], the start_latlng2 is also set like a string "["49,11", "49,12"]" which is fine and ok for me to be added to the database like this, but the column in sql keeps empty and I don´t know why because the property in the debugger is set correctly.
Can you once again maybe quickly explain how your suggestion
private string _start_latlng2;
public string start_latlng2
{
get { return _start_latlng2; }
set { _start_latlng2 = value; }
}
corresponds to transforming an object to an string? Your suggestion here just covers how you can access private fields with those getters and setters or? I really would like to understand how I can convert an object to string working with getters and setters. Maybe you can explain that once more, thank you very miuch Oliver!

Related

JsonConvert.DeserializeObject return null for the object instead of the overflow integer itself

I have the following data object.
public class myObject
{
public string user
{
get; set;
}
public List<available> available
{
get; set;
}
}
public class available
{
public string name
{
get; set;
}
public int points
{
get; set;
}
}
If I use JsonConvert.DeserializeObject to deserialize the following data (overflowed points)
{
"user":"12345",
"available":[
{
"name":"test",
"points":1234567891012345
}
]
}
it returns null for available object
but if I have the following class and
public class available
{
public int points
{
get; set;
}
}
deserialize the following data, it returns 0 for points.
{
"points": 1234567891012345,
}
Why did the first one returns null for the object?
First, suggestion is, please improve your question so we can help you answer accurately.
Second I can see exception in this scenario from newton soft because you are using output bound value for integer.
Newtonsoft.Json 13.0.2
You should see an error, something like below:
Unhandled exception. Newtonsoft.Json.JsonReaderException:
JSON integer 1234567891012345 is too large or small for an Int32.
Path 'available[0].points'```
Use a data type for your needs appropriately.

change propertyname base on variable [duplicate]

This question already has an answer here:
Can I set a property value with Reflection?
(1 answer)
Closed 2 years ago.
I have a QoL problem that i can figure out myself. See my below code with some explenations
public void UpdateStock(long? instID, float? Value, int counter,string KpiName)
{
{
List<KpiReturn> updateKpi = new List<KpiReturn>();
updateKpi.Add(new KpiReturn { instID = instID, KpiName = Value });
}
}
And a class with my properties looking like this:
public partial class KpiReturn
{
public long? instID { get; set; }
public double? peValue { get; set; }
public double? psValue { get; set; }
public double? pbValue { get; set; }
}
This code wont work because my kpiReturn dosent have a definition for "KpiName"
Right now i run 3 different if statements based on if i want the peValue,psValue,pbValue. But i want to add many more properties to this.
in the void UpdateStock code attached i have passed the string "psValue" to the KpiName.
is there any way that i can do to make the program understand that in the code
updateKpi.Add(new KpiReturn { instID = instID, KpiName = Value }
i want to pass the kpiName value instead of the actual name "kpiName"? ie psValue,pbValue or peValue
Sometimes it makes problems like this easier if you continue to break down the problem into smaller pieces. The right abstractions at the right level can be helpful which is the crux of #N-ate was suggesting when he mentioned breaking down the problem into smaller operations.
For example, so far you seem to have thought of the probem as requiring a big result object that holds everything. Sorta like this big ball of mud style object:
class KpiBigBallOfMudReturn
{
public long? instId { get; set; }
public double? peValue { get; set; }
public double? psValue { get; set; }
public double? pbValue { get; set; }
// lets keep adding many more properties to
// this class, make them nullable so we don't
// always have to set all of them....
// .. and more.. ...
}
But what you've also described is that you're creating values for that return separately and those things stand alone and have a name also. So if you create an abstraction around them it might look something like this:
class KpiValue
{
public string KpiId { get; set; }
public double Value { get; set; }
}
Here the KpiId is what you have as "KpiName" in your Update method.
#MarcGravell comment suggested using switches to select the right value based off name. Now that we have the pairs of name/values we can use a dictionary to do something similar - as #SeanSkelly suggested. We can replace the big ball of mud result object with something like this:
class KpiResult
{
readonly IDictionary<string, double> kpiValues;
public KpiResult(long instId, IEnumerable<KpiValue> values)
{
this.kpiValues = values.ToDictionary(k => k.KpiId, v => v.Value);
}
public double? this[string key]
{
get
{
if (this.kpiValues.TryGetValue(key, out var value))
return value;
return null;
}
}
}
Again this is just an example to illustrate the point that when you run into technical issues like this it's often helpful to see if you can solve them by making your design more SOLID

JSON Getting the value of a list based on the parameter

I have to process a complex JSON-file and I'm hitting some obstacles.
Below you will find a little excerpt from the class which is in XML but which I convert to JSON to be able to process it easier.
<Selection Category="M43002NN">
<ReferendumOptionIdentifier>foo</ReferendumOptionIdentifier>
<ValidVotes>6162</ValidVotes>
<CountMetric Id="M" Type="LevelDepositList">43002</CountMetric>
<CountMetric Id="S4" Type="SeatsToBeFilled">23</CountMetric>
<CountMetric Id="S5" Type="SubstitutesMax">0</CountMetric>
<CountMetric Id="S9" Type="LinguisticRegime">2</CountMetric>
<CountMetric Id="S10" Type="VotesDeposited">6620</CountMetric>
<CountMetric Id="S11" Type="BlankAndInvalidVotes">458</CountMetric>
<CountMetric Id="S12" Type="Alderman">0</CountMetric>
<CountMetric Id="S14" Type="ValidVote_E5">0</CountMetric>
<CountMetric Id="S15" Type="BlankAndInvalidVotes_E5">0</CountMetric>
</Selection>
In the above example I'm trying to extract the value of the CountMetric which has the type "SeatsToBeFilled".
So far I was able to collect the results and to isolate the correct CountMetric but I can't seem to get it's value.
This is my class:
public class TotalSelectionClass
{
[JsonProperty("#Category")]
public string Category { get; set; }
public int ValidVotes { get; set; }
public List<CountMetricClass> CountMetric { get; set; }
}
And this is the CountMetricClass that I use:
public class CountMetricClass
{
[JsonProperty("#Id")]
public string Id { get; set; }
[JsonProperty("#Type")]
public string Type { get; set; }
}
Below is the code that I use to get the desired CountMetric (slightly reduced code for readability-purposes):
var TotalSeats = Selection[0].CountMetric.Where(x => x.Type == "SeatsToBeFilled").First();
This returns the CountMetric-object to me but how do I extract the value from it? So in this case, how do I extract the number 23 from it?
Thank you.
The answer here really depends on the shape of your JSON and, thus, how you're doing your XML -> JSON conversion. You have not provided the JSON form nor asked for help in converting the XML -> JSON so I'll answer based on the information available.
As-is, you can't get the CountMetric value from your CountMetricClass. This is because the value held in the XML (looks like 23 for SeatsToBeFilled) is never read into that object. To get the value, you'll need to
1) check that your XML converter is actually encoding the value from the XML into the JSON to be parsed
2) modify your CountMetricClass so that it's reading from this value field. I've chosen to call this field MetricValue for readability, but you could obviously choose whatever name works best for you. For instance, your new class may take the form of something like:
public class CountMetricClass
{
[JsonProperty("#Id")]
public string Id { get; set; }
[JsonProperty("#Type")]
public string Type { get; set; }
[JsonProperty("#MetricValue")]
public int MetricValue { get; set; }
}
3) once we've successfully read the MetricValue into your CountMetricClass, we can modify your linq expression to get the value by accessing the MetricValue field from the target CountMetric like:
var TotalSeats = Selection[0].CountMetric.Where(x => x.Type == "SeatsToBeFilled").MetricValue;
A little follow-up for those who might run into the same issue.
Based on SIRHAMY's suggestion I had a look at the actual JSON which I was converting from XML.
{"#Id":"S4","#Type":"SeatsToBeFilled","#text":"23"}
As SIRHAMY suggested I created a Text-field in my CountMetricClass
public class CountMetricClass
{
[JsonProperty("#Id")]
public string Id { get; set; }
[JsonProperty("#Type")]
public string Type { get; set; }
[JsonProperty("#Text")]
public string Text { get; set; }
}
After that I could get the value of the text by using:
Selection[0].CountMetric.Where(x => x.Type == "SeatsToBeFilled").First().Text
This will return "23" to me.
Thank you SIRHAMY!

MVVM Additional Property for a Field

Maybe you can help me at the following issue.
I have a Model like this:
public class Lookup
{
private string _ValueName;
[Required]
public string ValueName
{
get
{
return _ValueName;
}
set
{
_ValueName = value;
}
}
}
In the ViewModel a can access Lookup.ValueName to get the Value of the item. But how i can get the Name of the DataColumn? I want to implement a new interface which will give me the Name but maybe it is a lot easier? I do not want to write the Name hardcoded.
Target is to write: Lookup.ValueName.DataColumnName
Thanks for helping
Tom
Consider this option:
public class Lookup
{
[Required]
public string ValueName { get; set; }
public string ValueNameDataColumnName => nameof(ValueName);
}

Using {set; get;} instead of {get; set;}

In C# and its cousin languages, we always use
public string SomeString { get; set;}
But you can also use ( I found this out only recently and while fooling around with the compiler )
public string SomeString { set; get; }
I do not have any formal training in programming and everything is self-tought. I have been using { get; set; } without any thought just like we use 1 + 1 = 2 Is the order of { get; set; } just a convention or is it necessary to maintain this order or is it some remnant of a bygone era of C history like the way we define conventional electric current flowing from positive to the negative terminal when it is actually the other way around?
It is purely a convention. It makes no difference which order they appear in.
There is no difference.
It is exactly as if you had implemented the getter first in your class body, and the setter after it. The functions would still do exactly the same:
public String getSomeString() { return someString; }
public void setSomeString(String value) { someString=value; }
Whether they are written in that order
public void setSomeString(String value) { someString=value; }
public String getSomeString() { return someString; }
or the opposite. Wouldn't they?
I would however suggest to stick to one order in your code. Less entropy is always better :)
There is no difference.
According to the C# Language Specification http://msdn.microsoft.com/en-us/library/ms228593.aspx, 10.7.2 Accessors (page 324)
The accessor-declarations of a property specify the executable
statements associated with reading and writing that property.
accessor-declarations:
get-accessor-declaration set-accessor-declaration
set-accessor-declaration get-accessor-declaration
As shown it states either order has the same effect
Internally Get and Set are methods like this
private PropertyType Get() {}
private Set(value as PropertyType) {}
Since order of declaration of methods is not important, same case goes here.
MSDN:
The body of the get accessor is similar to that of a method. It must return a value of the property type.
The set accessor is similar to a method that returns void. It uses an implicit parameter called value, whose type is the type of the property.
{ get; set; } is just a shortcut so you don't have to write getters and setters for every field you want to expose. It's the same as when you write
public string GetSomeString() { }
public void SetSomeString(string value) { }
Does it matter, which one you write first? Of course not.
Just a convention you can use any of these when defining parameters:
public string SomeString { get; set; }
public string SomeString2 { set; get; }
public string someString2;
public string SomeString21
{
get { return someString2; }
set { someString2 = value; }
}
public string SomeString22
{
set { someString2 = value; }
get { return someString2; }
}
public string SomeString23
{
set { someString2 = value; }
}
public string SomeString24
{
get { return someString2; }
}
As others have already pointed out, there is no difference and it is just a convention. But to prove that up, you can see how compiler actually treats your code, given the following:
public class C
{
public string SomeString { get; set;}
public string SomeString2 { set; get; }
}
This will be treated as:
public class C
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <SomeString>k__BackingField;
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <SomeString2>k__BackingField;
public string SomeString
{
[CompilerGenerated]
get
{
return <SomeString>k__BackingField;
}
[CompilerGenerated]
set
{
<SomeString>k__BackingField = value;
}
}
public string SomeString2
{
[CompilerGenerated]
get
{
return <SomeString2>k__BackingField;
}
[CompilerGenerated]
set
{
<SomeString2>k__BackingField = value;
}
}
}
As you can see, in both of them a new BackingField is generated by compiler and the body of two properties are same exactly.
The reference.

Categories