Search code examples
c#sql-serverentity-framework-corecomplex-numbers

How to store a C# Complex struct in SQL Server


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?


Solution

  • 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; }
    }