Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.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# 这是查询SQL Server CE表中的记录、填充和返回自定义对象的正确方法吗?_C#_Sql Server Ce_Compact Framework_Windows Ce - Fatal编程技术网

C# 这是查询SQL Server CE表中的记录、填充和返回自定义对象的正确方法吗?

C# 这是查询SQL Server CE表中的记录、填充和返回自定义对象的正确方法吗?,c#,sql-server-ce,compact-framework,windows-ce,C#,Sql Server Ce,Compact Framework,Windows Ce,下面的代码是有效的,但我想知道它是否比必要的更唠叨: public static InventoryItem SelectLocalInventoryItem(string ID) { const int ID_COL = 0; const int PACKSIZE_COL = 1; const int DESCRIPTION_COL = 2; const int DEPTDOTSUBDEPT_COL = 3; const int UNITCOST_COL

下面的代码是有效的,但我想知道它是否比必要的更唠叨:

public static InventoryItem SelectLocalInventoryItem(string ID)
{
    const int ID_COL = 0;
    const int PACKSIZE_COL = 1;
    const int DESCRIPTION_COL = 2;
    const int DEPTDOTSUBDEPT_COL = 3;
    const int UNITCOST_COL = 4;
    const int UNITLIST_COL = 5;
    const int UPCCODE_COL = 6;
    const int UPCPACKSIZE_COL = 7;
    const int CRVID_COL = 8;

    var invItem = new InventoryItem();
    using (var conn = new SqlCeConnection(dataSource))
    {
        var cmd = conn.CreateCommand();
        cmd.CommandText = "SELECT * FROM InventoryItems WHERE Id = @IDVal";

        var IDParam = cmd.CreateParameter();
        IDParam.ParameterName = "@IdVal";
        IDParam.Value = ID;
        cmd.Parameters.Add(IDParam);

        conn.Open();
        cmd.Prepare();
        using (var reader = cmd.ExecuteReader())
        {
            if (reader.Read())
            {
                invItem.Id = reader.GetString(ID_COL);
                invItem.PackSize = reader.GetInt16(PACKSIZE_COL); 
                invItem.Description = reader.GetString(DESCRIPTION_COL);
                invItem.DeptDotSubdept = reader.GetDouble(DEPTDOTSUBDEPT_COL); 
                invItem.Unit_Cost = reader.GetDouble(UNITCOST_COL);
                invItem.Unit_List = reader.GetDouble(UNITLIST_COL);
                invItem.UPC_code = reader.GetString(UPCCODE_COL);
                invItem.UPC_pack_size = reader.GetInt16(UPCPACKSIZE_COL); 
                invItem.CRV_Id = reader.GetInt32(CRVID_COL);
            }
        }
        conn.Close();
        cmd.Dispose();
        return invItem;
    }
}
正在查询的表是这样创建的:

using (var connection = new SqlCeConnection(dataSource))
{
    connection.Open();
    using (var command = new SqlCeCommand())
    {
        command.Connection = connection;

        if (TableExists(connection, "InventoryItems"))
        {
            command.CommandText = "DROP TABLE InventoryItems";
            command.ExecuteNonQuery();
        }
        command.CommandText = "CREATE TABLE InventoryItems (Id nvarchar(50) NOT 
            NULL, PackSize smallint NOT NULL, Description nvarchar(255), 
            DeptDotSubdept float, UnitCost float, UnitList float, UPCCode 
            nvarchar(50), UPCPackSize smallint, CRVId int);";
        command.ExecuteNonQuery();
    . . .
    }
}
该类声明如下:

public class InventoryItem
{
    public string Id { get; set; }
    public int PackSize { get; set; }
    public string Description { get; set; }
    public double DeptDotSubdept { get; set; }
    public double Unit_Cost { get; set; }
    public double Unit_List { get; set; }
    public string UPC_code { get; set; }
    public int UPC_pack_size { get; set; }
    public int CRV_Id { get; set; }
}
是否有一种更简单/更快的方法来实现这一点,或者我真的需要费力地手动将每个返回的列分配给每个类成员

更新 我实施了Sergey K的建议,现在是:

public static InventoryItem SelectLocalInventoryItem(string ID)
{
    InventoryItem invItem = null;
    using (var conn = new SqlCeConnection(dataSource))
    {
        var cmd = conn.CreateCommand();
        cmd.CommandText = "SELECT * FROM InventoryItems WHERE Id = @IDVal";

        var IDParam = cmd.CreateParameter();
        IDParam.ParameterName = "@IdVal";
        IDParam.Value = ID;
        cmd.Parameters.Add(IDParam);

        conn.Open();
        cmd.Prepare();
        using (var reader = cmd.ExecuteReader())
        {
            if (reader.Read())
            {
                invItem = new InventoryItem
                {
                    Id = Convert.ToString(reader["Id"]),
                    PackSize = Convert.ToInt16(reader["PackSize"]), 
                    Description = Convert.ToString(reader["Description"]), 
                    DeptDotSubdept = Convert.ToDouble(reader["DeptDotSubdept"]),
                    Unit_Cost = Convert.ToDouble(reader["UnitCost"]),
                    Unit_List = Convert.ToDouble(reader["UnitList"]),
                    UPC_code = Convert.ToString(reader["UPCCode"]),
                    UPC_pack_size = Convert.ToInt16(reader["UPCPackSize"]),
                    CRV_Id = Convert.ToInt32(reader["CRVId"])
                };
            }
        }
        return invItem;
    }
}
更新2 对于记录/后代,这里有一个相关的方法返回所有值,而不是一个“记录”/类实例:

public static List<InventoryItem> SelectLocalInventoryItems()
{
    List<InventoryItem> invItems = new List<InventoryItem>();
    using (var conn = new SqlCeConnection(dataSource))
    {
        var cmd = conn.CreateCommand();
        cmd.CommandText = "SELECT * FROM InventoryItems";
        conn.Open();
        cmd.Prepare();
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                var invItem = new InventoryItem
                {
                    Id = Convert.ToString(reader["Id"]),
                    PackSize = Convert.ToInt16(reader["PackSize"]),
                    Description = Convert.ToString(reader["Description"]),
                    DeptDotSubdept = Convert.ToDouble(reader["DeptDotSubdept"]),
                    Unit_Cost = Convert.ToDouble(reader["UnitCost"]),
                    Unit_List = Convert.ToDouble(reader["UnitList"]),
                    UPC_code = Convert.ToString(reader["UPCCode"]),
                    UPC_pack_size = Convert.ToInt16(reader["UPCPackSize"]),
                    CRV_Id = Convert.ToInt32(reader["CRVId"])
                };
                invItems.Add(invItem);
            }
        }
    }
    return invItems;
}
……为此:

    using (SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Scrollable))
    {
        cmd.Prepare();
        Object[] values = new Object[rs.FieldCount];
        int fieldCount = rs.GetValues(values);
        for (int i = 0; i < fieldCount; i++)
        {
            var invItem = new HHSUtils.InventoryItem
            {
                Id = Convert.ToString(rs["Id"]),
                PackSize = Convert.ToInt16(rs["PackSize"]),
                Description = Convert.ToString(rs["Description"]),
                DeptDotSubdept = Convert.ToDouble(rs["DeptDotSubdept"]),
                Unit_Cost = Convert.ToDouble(rs["UnitCost"]),
                Unit_List = Convert.ToDouble(rs["UnitList"]),
                UPC_code = Convert.ToString(rs["UPCCode"]),
                UPC_pack_size = Convert.ToInt16(rs["UPCPackSize"]),
                CRV_Id = Convert.ToInt32(rs["CRVId"])
            };
            invItems.Add(invItem);
        }
    }
}
??它似乎起作用了

更新6 对于后代来说,这似乎是一种很好的形式,对于SQL Server CE表上的“Select*”非常有效:

public static List<HHSUtils.Department> SelectLocalDepartments()
{
    var departments = new List<HHSUtils.Department>();
    using (var conn = new SqlCeConnection(dataSource))
    {
        conn.Open();
        SqlCeCommand cmd = conn.CreateCommand();
        cmd.CommandType = CommandType.TableDirect;
        cmd.CommandText = "Departments";
        using (SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.None))
        {
            var values = new Object[rs.FieldCount];
            while(rs.Read())
            {
                rs.GetValues(values);
                var dept = new HHSUtils.Department
                { 
                    Id = Convert.ToInt16(rs["Id"]),
                    DeptNumber = Convert.ToInt16(rs["DeptNum"]),
                    DeptName = Convert.ToString(rs["DepartmentName"]),
                };
                departments.Add(dept);
            }
        }
    }
    return departments;
}
publicstaticlist SelectLocalDepartments()
{
var departments=新列表();
使用(var conn=new SqlCeConnection(数据源))
{
conn.Open();
SqlCeCommand cmd=conn.CreateCommand();
cmd.CommandType=CommandType.TableDirect;
cmd.CommandText=“部门”;
使用(SqlCeResultSet rs=cmd.executesultset(resultstoptions.None))
{
var值=新对象[rs.FieldCount];
while(rs.Read())
{
rs.GetValues(值);
var dept=新的HHSUtils.部门
{ 
Id=转换为16(rs[“Id”]),
DeptNumber=Convert.ToInt16(rs[“DeptNum”]),
DeptName=Convert.ToString(rs[“DepartmentName”]),
};
部门。添加(部门);
}
}
}
返回部门;
}

我看你没有什么事情能做得更好

  • 为什么不使用列名从读取器获取值?差不多
  • Convert.ToDouble(读卡器[“DeptDotSubdept”]); 我认为在方法的作用域中使用常量来标识列号没有任何意义

  • 可以使用对象初始值设定项来实例化对象

    if(reader.Read())

  • 如果未找到记录,则返回空引用

  • 如果您知道使用的是什么,您可能不想添加这一行

    康涅狄格州关闭(); cmd.Dispose()


  • 我看没有什么事情你能做得更好

  • 为什么不使用列名从读取器获取值?差不多
  • Convert.ToDouble(读卡器[“DeptDotSubdept”]); 我认为在方法的作用域中使用常量来标识列号没有任何意义

  • 可以使用对象初始值设定项来实例化对象

    if(reader.Read())

  • 如果未找到记录,则返回空引用

  • 如果您知道使用的是什么,您可能不想添加这一行

    康涅狄格州关闭(); cmd.Dispose()


  • 我看没有什么事情你能做得更好

  • 为什么不使用列名从读取器获取值?差不多
  • Convert.ToDouble(读卡器[“DeptDotSubdept”]); 我认为在方法的作用域中使用常量来标识列号没有任何意义

  • 可以使用对象初始值设定项来实例化对象

    if(reader.Read())

  • 如果未找到记录,则返回空引用

  • 如果您知道使用的是什么,您可能不想添加这一行

    康涅狄格州关闭(); cmd.Dispose()


  • 我看没有什么事情你能做得更好

  • 为什么不使用列名从读取器获取值?差不多
  • Convert.ToDouble(读卡器[“DeptDotSubdept”]); 我认为在方法的作用域中使用常量来标识列号没有任何意义

  • 可以使用对象初始值设定项来实例化对象

    if(reader.Read())

  • 如果未找到记录,则返回空引用

  • 如果您知道使用的是什么,您可能不想添加这一行

    康涅狄格州关闭(); cmd.Dispose()


  • 值得注意的是,如果您在许多行中执行此操作,则可以大大提高速度。有两种改进途径:

  • 通过在迭代行之前首先缓存数值字段序号,使用
    reader.GetValues
    提取整个数据行,然后使用缓存的序号访问结果数组,可以实现适度的改进
  • 这样做更好的原因有两个。首先,它不需要读者总是根据您提供的名称查找序号,其次,它不需要对每个字段的数据进行往返

  • 只需使用
    TableDirect
    而不是SQL查询打开表,然后执行#1中的建议,就可以实现一个数量级的改进
  • 编辑

    大致如下:

    using (var rs = cmd.ExecuteResultSet())
    {
        var fieldCount = rs.fieldCount;
        var values = new Object[rs.FieldCount];
    
        // cache your ordinals here using rs.GetOrdinal(fieldname)
        var ID_ORDINAL = rs.GetOrdinal("Id");
        // etc
    
        while(rs.Read())
        {
            rs.GetValues(values);
    
            var invItem = new HHSUtils.InventoryItem
            {
                Id = (string)values[ID_ORDINAL],
                PackSize = (short)values[PACK_SIZE_ORDINAL],
                // etc
            };
            invItems.Add(invItem);
        }
    }
    
    编辑2

    可能值得注意的是,如果使用类似的代码,则执行上述操作的代码如下所示:

    invItems = store.Select<InventoryItem>();
    
    invItems=store.Select();
    

    就这样,就一行。默认情况下,它会使用
    TableDirect

    值得注意的是,如果您跨许多行执行此操作,则可以大大提高速度。有两种改进途径:

  • 通过在迭代行之前首先缓存数值字段序号,使用
    reader.GetValues
    提取整个数据行,然后使用缓存的序号访问结果数组,可以实现适度的改进
  • 这样做更好的原因有两个。首先,它不需要读者总是根据您提供的名称查找序号,其次,它不需要对每个字段的数据进行往返

  • 只需使用
    TableDirect
    而不是SQL查询打开表,然后执行#1中的建议,就可以实现一个数量级的改进
  • 编辑

    大致如下:

    using (var rs = cmd.ExecuteResultSet())
    {
        var fieldCount = rs.fieldCount;
        var values = new Object[rs.FieldCount];
    
        // cache your ordinals here using rs.GetOrdinal(fieldname)
        var ID_ORDINAL = rs.GetOrdinal("Id");
        // etc
    
        while(rs.Read())
        {
            rs.GetValues(values);
    
            var invItem = new HHSUtils.InventoryItem
            {
                Id = (string)values[ID_ORDINAL],
                PackSize = (short)values[PACK_SIZE_ORDINAL],
                // etc
            };
            invItems.Add(invItem);
        }
    }
    
    编辑2

    也许值得注意的是,如果你
    {
        invItem = new InventoryItem{
          Id = Convert.ToString(reader["Id"]),
        .....
        };
    }
    
    using (var rs = cmd.ExecuteResultSet())
    {
        var fieldCount = rs.fieldCount;
        var values = new Object[rs.FieldCount];
    
        // cache your ordinals here using rs.GetOrdinal(fieldname)
        var ID_ORDINAL = rs.GetOrdinal("Id");
        // etc
    
        while(rs.Read())
        {
            rs.GetValues(values);
    
            var invItem = new HHSUtils.InventoryItem
            {
                Id = (string)values[ID_ORDINAL],
                PackSize = (short)values[PACK_SIZE_ORDINAL],
                // etc
            };
            invItems.Add(invItem);
        }
    }
    
    invItems = store.Select<InventoryItem>();