Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-如何在数据库中存储双数组?_C#_.net_Database_Visual Studio_Database Design - Fatal编程技术网

C#-如何在数据库中存储双数组?

C#-如何在数据库中存储双数组?,c#,.net,database,visual-studio,database-design,C#,.net,Database,Visual Studio,Database Design,我有一个大的双倍数组,它是一个物体的一部分。这些对象将存储在数据库中。我创建了一个表,其中包含每个字段。我一直想弄清楚如何在表中存储这个大数组。我不必在每列中创建另一个具有这些双精度的表,因为每个对象的数组大小是可变的,而且它们非常大。因此,在设置数据库时,遍历表并添加数千个浮动将非常耗时 如何将这个双精度数组存储到列中 我只需要更多的识别列 阿拉伊德 ArrayIndex ArrayIndex(如果二维阵列需要) 价值观 这将允许您拥有一个不需要添加额外列的表,尽管需要存储的数据大小不同

我有一个大的双倍数组,它是一个物体的一部分。这些对象将存储在数据库中。我创建了一个表,其中包含每个字段。我一直想弄清楚如何在表中存储这个大数组。我不必在每列中创建另一个具有这些双精度的表,因为每个对象的数组大小是可变的,而且它们非常大。因此,在设置数据库时,遍历表并添加数千个浮动将非常耗时


如何将这个双精度数组存储到列中

我只需要更多的识别列

  • 阿拉伊德
  • ArrayIndex
  • ArrayIndex(如果二维阵列需要)
  • 价值观
这将允许您拥有一个不需要添加额外列的表,尽管需要存储的数据大小不同

如果列被正确索引,那么存储数千或数百万条记录就没有什么大不了的了


祝你好运

我会有更多的识别栏

  • 阿拉伊德
  • ArrayIndex
  • ArrayIndex(如果二维阵列需要)
  • 价值观
这将允许您拥有一个不需要添加额外列的表,尽管需要存储的数据大小不同

如果列被正确索引,那么存储数千或数百万条记录就没有什么大不了的了


祝您好运

将double数组打包到模型上的其他属性中,并保存序列化数据。最快的打包算法是。我在一个生产应用程序中使用了以下内容,该应用程序在阵列中存储了大约450万个

请注意,我将此剥离到最低限度,您可能希望优化打包/解包调用,以便它们不会在每次访问属性时发生

在下面的示例中,我们将
Surface
保存到数据库中,该数据库包含一个扫描数组,其中包含一个样本数组。同样的概念也适用于double[]的属性

[ProtoBuf.ProtoContract]
public class Sample
{
    public Sample()
    {
    }

    [ProtoBuf.ProtoMember(2)]
    public double Max { get; set; }

    [ProtoBuf.ProtoMember(3)]
    public double Mean { get; set; }

    [ProtoBuf.ProtoMember(1)]
    public double Min { get; set; }
}

[ProtoBuf.ProtoContract]
public class Scan
{
    public Scan()
    {
    }

    [ProtoBuf.ProtoMember(1)]
    public Sample[] Samples { get; set; }
}

public class Surface
{
    public Surface()
    {
    }

    public int Id { get; set; }

    public byte[] ScanData { get; set; }

    [NotMapped]
    public Scan[] Scans
    {
        get
        {
            return this.Unpack();
        }
        set
        {
            this.ScanData = this.Pack(value);
        }
    }

    private byte[] Pack(Scan[] value)
    {
        using (var stream = new MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(stream, value);
            return stream.ToArray();
        }
    }

    private Scan[] Unpack()
    {
        using (var stream = new MemoryStream(this.ScanData))
        {
            return ProtoBuf.Serializer.Deserialize<Scan[]>(stream);
        }
    }
}
[ProtoBuf.ProtoContract]
公共类样本
{
公共样本()
{
}
[原成员(2)]
公共双最大值{get;set;}
[原成员(3)]
公共双均值{get;set;}
[原成员(1)]
公共双最小值{get;set;}
}
[ProtoBuf.ProtoContract]
公共类扫描
{
公共扫描()
{
}
[原成员(1)]
公共样本[]样本{get;set;}
}
公共类表面
{
公共场地()
{
}
公共int Id{get;set;}
公共字节[]扫描数据{get;set;}
[未映射]
公共扫描[]扫描
{
得到
{
返回此文件。解包();
}
设置
{
this.scanda=this.Pack(值);
}
}
专用字节[]包(扫描[]值)
{
使用(var stream=new MemoryStream())
{
ProtoBuf.Serializer.Serialize(流,值);
返回流ToArray();
}
}
专用扫描[]解包()
{
使用(var stream=newmemoryStream(this.scanda))
{
返回ProtoBuf.Serializer.Deserialize(流);
}
}
}

将double数组打包到模型上的其他属性中,并保存序列化数据。最快的打包算法是。我在一个生产应用程序中使用了以下内容,该应用程序在阵列中存储了大约450万个

请注意,我将此剥离到最低限度,您可能希望优化打包/解包调用,以便它们不会在每次访问属性时发生

在下面的示例中,我们将
Surface
保存到数据库中,该数据库包含一个扫描数组,其中包含一个样本数组。同样的概念也适用于double[]的属性

[ProtoBuf.ProtoContract]
public class Sample
{
    public Sample()
    {
    }

    [ProtoBuf.ProtoMember(2)]
    public double Max { get; set; }

    [ProtoBuf.ProtoMember(3)]
    public double Mean { get; set; }

    [ProtoBuf.ProtoMember(1)]
    public double Min { get; set; }
}

[ProtoBuf.ProtoContract]
public class Scan
{
    public Scan()
    {
    }

    [ProtoBuf.ProtoMember(1)]
    public Sample[] Samples { get; set; }
}

public class Surface
{
    public Surface()
    {
    }

    public int Id { get; set; }

    public byte[] ScanData { get; set; }

    [NotMapped]
    public Scan[] Scans
    {
        get
        {
            return this.Unpack();
        }
        set
        {
            this.ScanData = this.Pack(value);
        }
    }

    private byte[] Pack(Scan[] value)
    {
        using (var stream = new MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(stream, value);
            return stream.ToArray();
        }
    }

    private Scan[] Unpack()
    {
        using (var stream = new MemoryStream(this.ScanData))
        {
            return ProtoBuf.Serializer.Deserialize<Scan[]>(stream);
        }
    }
}
[ProtoBuf.ProtoContract]
公共类样本
{
公共样本()
{
}
[原成员(2)]
公共双最大值{get;set;}
[原成员(3)]
公共双均值{get;set;}
[原成员(1)]
公共双最小值{get;set;}
}
[ProtoBuf.ProtoContract]
公共类扫描
{
公共扫描()
{
}
[原成员(1)]
公共样本[]样本{get;set;}
}
公共类表面
{
公共场地()
{
}
公共int Id{get;set;}
公共字节[]扫描数据{get;set;}
[未映射]
公共扫描[]扫描
{
得到
{
返回此文件。解包();
}
设置
{
this.scanda=this.Pack(值);
}
}
专用字节[]包(扫描[]值)
{
使用(var stream=new MemoryStream())
{
ProtoBuf.Serializer.Serialize(流,值);
返回流ToArray();
}
}
专用扫描[]解包()
{
使用(var stream=newmemoryStream(this.scanda))
{
返回ProtoBuf.Serializer.Deserialize(流);
}
}
}
您应该使用单独的表格 你不应该试图对你的数据进行黑客格式化,这会让你很难说出你想做什么,也会让你在功能层面上想做的事情变得混乱

你为什么需要另一张桌子 您需要一个链接表的原因是,您不知道将要保存多少数据,即使您将其放入blob中(如果您有可能超过blob中可以保存的最大数据量)

代码 我想为吸收点创建一个单独的对象,并将其存储在字典中,这样,如果您有一些经常发生的默认情况(比如在某个点上找不到任何东西),您就不需要存储整个内容

虽然最好是创建一个单独的类来表示集合,但是如果有人重用该类并且不知道发生了什么,他们就不会添加不必要的数据

CREATE TABLE SpectroscopyObject ( Id INT PRIMARY KEY NOT NULL, --other stuff )

CREATE TABLE FrequencyAbsorptionInfo ( Id INT PRIMARY KEY NOT NULL IDENTITY, XCoord INT NOT NULL, YCoord INT NOT NULL, AbsorptionInfo NUMERIC(5,5) NOT NULL, SpectroscopyObjectId INT NOT NULL FOREIGN KEY REFERENCES SpectroscopyObject(Id) )
string commandStringSObjs = 
@"
SELECT Id, ..other attributes... FROM SpectroscopyObject
";
string commandStringCoords = 
@"
SELECT XCoord,YCoord,AbsorptionInfo 
WHERE SpectroscopyObjectId = @Id
";

var streoscopicObjs = new List<SpectroscopyObject>();
using(var connection = new SqlConnection(CONNECTION_STRING))
{
    using(var cmd = connection.CreateCommand())
    {
        cmd.CommandText = commandStringSObjs;
        connection.Open();
        using(var rdr = cmd.ExecuteReader())
        {
            while(rdr.Read())
            {

                streoscopicObjs.Add(new SpectroscopyObject
                {
                    Id = Convert.ToInt32(rdr["Id"])
                    //populate your other stuff
                }
            }
        }
    }
    //to read the absorption info
    foreach(var obj in streoscopicObjs)
    {
        var current = obj.FrequecyAbsorption;
        using(var cmd = connection.CreateCommand())
        { 
            cmd.CommandText = commandStringCoords;
            cmd.Parameters.Add(
                new SqlParameter("Id",DbType.Int){ Value = obj.Id});
            using(var rdr = cmd.ExecuteReader())
            {
                while(rdr.Read())
                {
                    var x = Convert.ToInt32(rdr["XCoord"]);
                    var y = Convert.ToInt32(rdr["YCoord"]);
                    var freq = Convert.ToDouble(rdr["AbsorptionInfo"]);

                    current[x][y] = new FrequencyAbsorptionPoint
                    {
                        Location = new Point(x,y),
                        Frequency = freq
                    };
                }
            }
        }
    }

    //do some stuff
    ...
   // assuming you update 
    string updatefreq = 
@"


INSERT INTO FrequencyAbsorptionInfo(XCoord,YCoord,
                   AbsorptionInfo,SpectroscopyObjectId )
VALUES(@xvalue,@yvalue,@freq,@Id) ";
    //other point already

    //to write the absorption info
    foreach(var obj in streoscopicObjs)
    {
        using(var cmd = connection.CreateCommand())
        {
            cmd.CommandText = 
@"
DELETE FrequencyAbsoptionInfo 
WHERE  SpectroscopyObjectId =@Id
";
            cmd.Parameters.Add(new SqlParameter("Id",DbType.Int){ Value = obj.Id});
            cmd.ExecuteNonQuery();
        }
        var current = obj.FrequecyAbsorption;
        foreach(var freq in current)
        {
            using(var cmd = connection.CreateCommand())
            { 
                cmd.CommandText = updatefreq ;
                cmd.Parameters.AddRange(new[]
                {
                    new SqlParameter("Id",DbType.Int){ Value = obj.Id},
                    new SqlParameter("XCoords",DbType.Int){ Value = freq.Location.X},
                    new SqlParameter("YCoords",DbType.Int){ Value = freq.Location.Y},
                    new SqlParameter("freq",DbType.Int){ Value = freq.Frequency },
                });
                cmd.ExecuteNonQuery();
            }
        }
    }
}