在单个数据块中包含不同类型变量的最佳方法是什么? [英] What is the best way to contain different types of variables in a single blob of data?

查看:78
本文介绍了在单个数据块中包含不同类型变量的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好:



我正在创建一个工作表应用程序。有一组共同的字段(即名称,出生日期,一些文本字段等)然后有一个代码会提出一系列问题。



每个代码可以有不同的问题,可以有不同的类型(即字符串,整数,浮点数等)



所以我想是有一个名称,生日和代码作为文件密钥的数据库,以及一个4096字节的blob(任何代码的字段数都不能超过这个大小)。



我正在为属于代码的每组问题创建结构,并将它们复制进出blob,但它似乎不起作用。无论我尝试什么,我都会尝试写入受保护的代码错误,或者信息显示为乱码,或者最新的信息,不能作为非托管结构进行编组;不能计算有意义的大小或偏移量。



最好的方法是什么?我的一个示例'代码'结构如下:

Hello all:

I am creating a worksheet application. There is a common set of fields (i.e. name, Birthdate, some text fields, etc.) Then there is a 'code' that brings up a set of questions.

Each code can have a different amount of questions, and could have different types (i.e. string, int, float, etc.)

So what I figured is to have a Database with the name, birthdate, and code as the key to the file, and a 4096 byte 'blob' (no amount of fields for any code can go over this size).

I was creating 'structs' for each set of questions that belong to a code, and copying them in and out of the 'blob', but it doesn't seem to be working. No matter what I try, I get either 'attempting to write to protected code' errors, or the information appears garbled, or the newest one, "cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."

What is the best way to do this? One of my example 'code' structs is below:

public partial class Code1 : Form
{
    private new frmMain ParentForm;
    private Code1_Record ws = new Code1_Record();

    public Code1(frmMain _parent, byte[] _record)
    {
        InitializeComponent();
        ParentForm = _parent;

        if (_record != null)
        {
            LoadData(_record);
        }
    }

    private void LoadData(byte[] _record)
    {
        //int iSize = Marshal.SizeOf(ws);
        //byte[] bTmp = new byte[iSize];
        //Array.Copy(_record, 0, bTmp, 0, iSize);
        ws = FromBytes(_record);

        tbxL_CFA.Text = ws.fL_CFA;
        tbxL_SFAprox.Text = ws.fL_SFAprox;
        tbxL_SFAmid.Text = ws.fL_SFAmid;
        tbxL_SFAdistal.Text = ws.fL_SFAdistal;
        tbxL_POP.Text = ws.fL_POP;
        tbxL_PTA.Text = ws.fL_PTA;
        tbxL_DPA.Text = ws.fL_DPA;

        chbL_CFA.Checked = ws.bL_CFA;
        chbL_SFAprox.Checked = ws.bL_SFAprox;
        chbL_SFAmid.Checked = ws.bL_SFAmid;
        chbL_SFAdistal.Checked = ws.bL_SFAdistal;
        chbL_POP.Checked = ws.bL_POP;
        chbL_PTA.Checked = ws.bL_PTA;
        chbL_DPA.Checked = ws.bL_DPA;

        tbxR_CFA.Text = ws.fR_CFA;
        tbxR_SFAprox.Text = ws.fR_SFAprox;
        tbxR_SFAmid.Text = ws.fR_SFAmid;
        tbxR_SFAdistal.Text = ws.fR_SFAdistal;
        tbxR_POP.Text = ws.fR_POP;
        tbxR_PTA.Text = ws.fR_PTA;
        tbxR_DPA.Text = ws.fR_DPA;

        chbR_CFA.Checked = ws.bR_CFA;
        chbR_SFAprox.Checked = ws.bR_SFAprox;
        chbR_SFAmid.Checked = ws.bR_SFAmid;
        chbR_SFAdistal.Checked = ws.bR_SFAdistal;
        chbR_POP.Checked = ws.bR_POP;
        chbR_PTA.Checked = ws.bR_PTA;
        chbR_DPA.Checked = ws.bR_DPA;
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        ws.fL_CFA = tbxL_CFA.Text;
        ws.fL_SFAprox = tbxL_SFAprox.Text;
        ws.fL_SFAmid = tbxL_SFAmid.Text;
        ws.fL_SFAdistal = tbxL_SFAdistal.Text;
        ws.fL_POP = tbxL_POP.Text;
        ws.fL_PTA = tbxL_PTA.Text;
        ws.fL_DPA = tbxL_DPA.Text;

        ws.bL_CFA = chbL_CFA.Checked;
        ws.bL_SFAprox = chbL_SFAprox.Checked;
        ws.bL_SFAmid = chbL_SFAmid.Checked;
        ws.bL_SFAdistal = chbL_SFAdistal.Checked;
        ws.bL_POP = chbL_POP.Checked;
        ws.bL_PTA = chbL_PTA.Checked;
        ws.bL_DPA = chbL_DPA.Checked;

        ws.fR_CFA = tbxR_CFA.Text;
        ws.fR_SFAprox = tbxR_SFAprox.Text;
        ws.fR_SFAmid = tbxR_SFAmid.Text;
        ws.fR_SFAdistal = tbxR_SFAdistal.Text;
        ws.fR_POP = tbxR_POP.Text;
        ws.fR_PTA = tbxR_PTA.Text;
        ws.fR_DPA = tbxR_DPA.Text;

        ws.bR_CFA = chbR_CFA.Checked;
        ws.bR_SFAprox = chbR_SFAprox.Checked;
        ws.bR_SFAmid = chbR_SFAmid.Checked;
        ws.bR_SFAdistal = chbR_SFAdistal.Checked;
        ws.bR_POP = chbR_POP.Checked;
        ws.bR_PTA = chbR_PTA.Checked;
        ws.bR_DPA = chbR_DPA.Checked;

        ws.bPlaque = chbPlaque.Checked;
        ws.sLocation = tbxLocation.Text;

        ParentForm.CloseExamForm(ToBytes(ws));
        this.Close();
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
        // Check to see if any data changed
        ParentForm.CloseExamForm(null);
        this.Close();
    }

    #region Record Layout and Methods to and from byte[]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct Code1_Record
    {
        //Left Measurements
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_CFA;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_SFAprox;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_SFAmid;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_SFAdistal;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_POP;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_PTA;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fL_DPA;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        //Left 'Abnormal' (true/false)
        public bool bL_CFA;
        public bool bL_SFAprox;
        public bool bL_SFAmid;
        public bool bL_SFAdistal;
        public bool bL_POP;
        public bool bL_PTA;
        public bool bL_DPA;

        //Right Measurements
        public string fR_CFA;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fR_SFAprox;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fR_SFAmid;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fR_SFAdistal;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fR_POP;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fR_PTA;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string fR_DPA;
        //Right 'Abnormal' (true/false)
        public bool bR_CFA;
        public bool bR_SFAprox;
        public bool bR_SFAmid;
        public bool bR_SFAdistal;
        public bool bR_POP;
        public bool bR_PTA;
        public bool bR_DPA;

        //Plaque
        public bool bPlaque;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string sLocation;
    }

    private byte[] ToBytes(Code1_Record str)
    {
        int size = Marshal.SizeOf(str);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.StructureToPtr(str, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);

        return arr;
    }

    private Code1_Record FromBytes(byte[] arr)
    {
        Code1_Record str = new Code1_Record();

        int size = Marshal.SizeOf(str);
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.Copy(arr, 0, ptr, size);

        str = (Code1_Record)Marshal.PtrToStructure(ptr, str.GetType());
        Marshal.FreeHGlobal(ptr);

        return str;
    }
}
    #endregion





请您提前帮助我。



Thak you very much in advance for helping me.

推荐答案

最好的方法是没有不同类型的变量甚至blob中相同类型的不同变量。它会破坏关系模型的目的。



但在极少数情况下你真的可以从这种方法中受益(很难,但我不想再进一步讨论),方法可能是序列化

http://en.wikipedia.org/wiki/Serialization [ ^ ],

https://msdn.microsoft.com/en-us/library/ms973893.aspx [ ^ ],

https://msdn.microsoft.com/en-us/library/7ay27kt9%28v=vs.110%29.aspx [ ^ ],

https://msdn.microsoft.com/en-us/library/ms733127%28v=vs .110%29.aspx [ ^ ](最强大,一致且易于使用的序列化方法)。



-SA
The best way is not having "different types of variables" or even different variables of the same type in a blob. It would defeat the purpose of the relational model.

But in rare cases you really can benefit from this approach (hardly, but I don't want to discuss it any further), the approach could be serialization:
http://en.wikipedia.org/wiki/Serialization[^],
https://msdn.microsoft.com/en-us/library/ms973893.aspx[^],
https://msdn.microsoft.com/en-us/library/7ay27kt9%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/ms733127%28v=vs.110%29.aspx[^] (most robust, consistent and easy to use serialization approach).

—SA


谢谢 - 序列化做了我想要的:



Thank you - Serialization did what I wanted:

private byte[] ObjectToByteArray(Object obj)
{
    if (obj == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

private Object ByteArrayToObject(byte[] bArray)
{
    if (bArray == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream(bArray))
    {
        return bf.Deserialize(ms);
    }
}


这篇关于在单个数据块中包含不同类型变量的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆