How to store a C# Complex struct in SQL Server - c#

I have a Complex number in a C# class
public class DataToStore
{
[Key]
public int Id { get; set; }
public System.Numerics.Complex ComplexValue { get; set; }
}
I need to store this data in a SQL Server database, but I don't know what the equivalent type is in SQL.
For now, I'm trying to generate the database schema using Entity Framework Core, but when creating the migration EF is complaining that it can't map this type:
The property 'DataToStore.ComplexValue' could not be mapped because it
is of type 'Complex', which is not a supported primitive type or a
valid entity type. Either explicitly map this property, or ignore it
using the '[NotMapped]' attribute or by using
'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
Which makes sense, but I don't know how this data can be represented in SQL.
I'm not specifically tied to using Entity Framework - I'm only using this as a way to quickly mock up the database - so if this is something that can be done manually in SQL but not EF, then that's absolutely fine. My aim here is to get this data in the database and be able to get it out again in exactly the same format.
What's the best way of storing this type of data in SQL? Or does this value need converting to another type so that it can be stored?

You would need multiple database fields to store its values. If you want to store the Real and Imaginary values, you could have a field for each of them.
You would need to update your model so that EF does not try to save ComplexValue. You should have properties for the real and imaginary values and use them to make your complex value.
public class DataToStore
{
[Key]
public int Id { get; set; }
[NotMapped]
public System.Numerics.Complex ComplexValue
{
get
{
return new Complex(Real, Imaginary)
}
set
{
Real = value.Real;
Imaginary = value.Imaginary;
}
}
public double Real { get; set; }
public double Imaginary { get; set; }
}

Related

What is best approach for data inheritation in elasticsearch?

I have an parent class and two child like these:
public class Parent {
public Guid Id { get; set; }
public string Name { get; set; }
}
public class FirstChild {
public string IdentityCode { get; set; }
}
public class OtherChild {
public string RegistrationCode { get; set; }
}
There is a question: Is it a good approach to store these two inherited classes in the same Index inside ElasticSearch?
I see there is a _type property that is added to my docs after they are stored in DB but it has always "doc" value.
I test this code to fill it but it seems it is not working this way.
await ElasticClient.IndexAsync<FirstChild>(child, m => m.Index(IndexName));
And Also, I found this question on SO for retrieving my entries from DB but it is outdated and the API is changed and no more accessible.
I want to know if it is a good approach to store sibling data in the same index how can I do this properly.
As of ES 6.0, it is not possible anymore to store multiple types inside the same index, i.e. the _type field you're referring to will always be either doc or _doc. In ES 8.0, the _type field will be removed altogether.
However, if it makes sense for your use case, you can still decide to store several types inside a single index using a custom type field that is present in your document.
You should strive to only store in the same index data that share the same (or very similar) mapping, which doesn't seem to be the case for Parent, FirstChild and SecondChild, but if you add a public string type property to your classes you can still do it.

Entity framework adding properties to my class (over my head)

I'm trying to create a datastructure with entity framework to basically store property values of my objects. I want users to add properties to a class at runtime. The properties can be of different datatypes. (string/int/float etc..)
So I thought I needed some tables/classes as defined in the image below.
So my Object class contains a list of properties that are of a type defined in de propertydefinition class.
One hard thing is that values are stored in the table of the datatype of the propertie. (So a conditional foreignKey?)
Please give me some pointers on how to implement this by using Fluent API. Or other ideas on this subject. (I guess I won't be the first ;)
Werner
The EF entity model cannot be changed during Runtime (or at least is not designed for). You could use an infrastructure to store propertyname/propertyvalye with EF but I think is not the right choice (you lose most of the functionalities).
The best choice could be a NoSQL db, ADO.Net or, if only some objects can be personalized and other are fixed you could store the personalizable objects in XML/JSON in a text field.
I found this link
This helped me solve my "Table Per Type" question. I now have:
public abstract class PropertyBase
{
public int PropertyID { get; set; }
public string Name { get; set; }
}
public class TextProperty : PropertyBase
{
public string Value { get; set; }
}
public class IntProperty : PropertyBase
{
public int Value { get; set; }
}
In My Database Context I added:
modelBuilder.Entity<PropertyBase>()
.HasKey(p => p.PropertyID)
.ToTable("Properties");
modelBuilder.Entity<IntProperty>()
.ToTable("IntProperties");
modelBuilder.Entity<TextProperty>()
.ToTable("TextProperties");
The different types of properties (sub classes) are now stored in separate tables. The main abstract class contains all the other info. This worked fine for me.

Is it possible with Entity Framework to (de)serialize an object property from/to to string?

I'm going to create some tables with Entity Framework and the code-first approach. However some of my classes have complex properties like:
public class Car
{
public ComplexDate DateBought { get; set; }
}
where ComplexDate is:
public class ComplexDate
{
public int? Year { get; set; } // Notice the optional Year.
public string Month { get; set; }
public int Day { get; set; }
}
and can parse values like 27AUG or 27AUG15
Can I somehow configure my Car or ComplexDate so that I can serialize it into a string or deserialize back from a string? I'd like to have a column in the database called DateBought but in code I wish I could use the ComplexDate type for it and be able to parse the value stored in the database.#
IMPORTANT:
I have a few other complex properties that are not dates but are parsable that I'd like to store as strings as well and not in still more tables/column. It would overnomalize the database. I think I don't need it.
UPDATE:
Here's another example of what I mean:
public class Car
{
public CarColor Color { get; set; }
}
public class CarColor
{
private string _value;
// ...more code (ctr, parse etc.)
public override string ToString()
{
return _value;
}
}
Now I'd like to have a Car-table with a column named Color that would automatically (by some magic) turn into CarColor in code... Is there a way? Making the Color property (and others) a string breaks the whole design of my application because each an every property is a complex type because it has some logic for parsing, allowed values etc. I'd like it to be consistent (everything is complex type) instead of mixing string and classes and other types.
IMHO you probably want the EF property to be DateTime and just do the conversion in the UI. That way you can bind to a proper database date column and be able to do all the sorting and querying that would be impossible if use your approach.
You could store the date fields individually.
One for Year (nullable), one for Month, one for Day.
That way, you can still sort, group etc. from the database, and use the values in your class to combine and display as you wish.

How to work with advanced entities which does not fit table data in MVC?

Lets say we have a Person entity which fits table exactly:
public class Person
{
public int Id { get; set; }
public int Type { get; set; }
}
Now user have a type, and only if user is of specific type I want to be able to find out what is the Name of that type that person is. Right now I just add extra property on to the entity:
public class Person
{
public int Id { get; set; }
public int Type { get; set; }
public string TypeName { get; set; }
}
But I want to let my entities stay as clean as possible.
Do I need to create a separate "advanced entities" classes for this cases or how do I get around those cases?
PS. I am using stored procedures.
Your question is not clear but i think you are mixing view models with entities. If you want to store your user "Type" into the database then, yes you have to add a new field in your entity ( or use partial classes ) OR if you are using database first then add the field in your table and refresh your edmx . If you don't want to store it in database, just create a view model and use it on our UI.
Change that name to something specific about a person, whatever you want to track about a person (HairColor, EyeColor, Nationality, Size) anything but just plain "Type", which is a system base class in C#.
yes... use partial clases with extended properties inside them

An alternative lookup table approach needed to make C# models more generic

I currently have the following Models in my EF Code First MVC project (edited for brevity):
public class Car
{
public int Id { get; set; }
public string Descrip { get; set; }
// Navigation Property.
public virtual CarColour CarColour { get; set; }
... + numerous other navigation properties.
}
public class CarColour
{
public int Id { get; set; }
public string ColourName { get; set; }
}
The CarColour table in the DB contains many rows.
In my project, I have about 10 of these sorts of tables, which are essentially lookup tables.
Rather than have 10 lookup tables (and 10 corresponding 'hard' types in code), I was tasked with implementing a more re-usable approach, instead of having loads of lookup tables, specific to Car (in this example), along the lines of having a couple of tables, one of which may hold the item types (colour, fuel-type etc.) and one which contains the various values for each of the types. The idea being that our model will be able to be re-used by many other projects - some of which will have potentially hundreds of different attributes, and as such, we won't want to create a new Class/Type in code and generate a new lookup table for each.
I am having difficulty in understanding the c# implementation of this sort of approach and hope someone may be able to give me an example of how this can be achieved in code, more specifically, how the above models would need to change, and what additional classes would be required to accomplish this?
your base entity must implement INotifyPropertyChanged and make it generic:
public virtual CarColour CarColour {
Get { return this.carColour; }
Set {
this.Carcolour; = value
OnPropertyChanged("CarColour");
}
}
For more info see :
patterns & practices: Prism in CodePlex.
http://compositewpf.codeplex.com/wikipage?title=Model%20View%20ViewModel%20(MVVM)
Greetings
Bassam
This is not necessarily specific to EF but I've been down this road and didn't really enjoy it.
I wanted to use a single table to represent 'generic' information and while I thought it was smart, it soon showed it's limitations. One of them being the complexity you need to introduce when writing queries to extract this data if you're performing more than just 'get colours for this car'.
I'd say, if your data is simple key/value and the value type is always going to be the same then go for it, it might even be worth having this a mere 'meta-data' for an object:
public class Car
{
public int Id { get; set; }
public string Descrip { get; set; }
public MetaData CarColours { get; set; }
}
public MetaData : Dictionary<int, string>
{
public MetaData(int group){}
}
Hypothetical table:
TableMetaData(int metaGroup, int metaId, string metaValue)
If you're hoping to store different types as your value and may need to perform joining on this data - avoid it and be a bit more specific.

Categories