使用MySQL在Delphi中使用Enum填充组合框

使用MySQL在Delphi中使用Enum填充组合框,mysql,delphi,enums,Mysql,Delphi,Enums,我有一个EnumTRole type TRole = (Admin, Common); 在我的数据库(MySQL)中,我有一个表users,其中有一列role,类型为INTEGER。我希望以以下方式使用角色填充组合框: 组合框应在角色Admin中显示“管理员”,在角色Common中显示“普通用户”;当我将值保存到数据库时,对于Admin角色,它应该保存为0;对于Common角色,它应该保存为1(它们各自的索引) 另外,当显示角色字段时,它应该显示为上面显示的字符串 有人能解释一下我该怎么做

我有一个EnumTRole

type
  TRole = (Admin, Common);
在我的数据库(MySQL)中,我有一个表users,其中有一列role,类型为INTEGER。我希望以以下方式使用角色填充组合框: 组合框应在角色
Admin
中显示“管理员”,在角色
Common
中显示“普通用户”;当我将值保存到数据库时,对于
Admin
角色,它应该保存为0;对于
Common
角色,它应该保存为1(它们各自的索引)

另外,当显示角色字段时,它应该显示为上面显示的字符串


有人能解释一下我该怎么做吗?

我用了两种不同的方法来解决这个问题。一种方法是使用RTTI从枚举中派生名称,但在您的情况下,这不起作用,因此这里是我的另一种方法,它更具暴力性:

(您可以根据自己的使用进行调整-注意,我的实际函数来自类,但这并不重要)

然后在下拉列表中填入如下内容

procedure FillComboBox( Const pComboBox : TComboBox )
var
  iRole : TRole;
begin
  pComboBox.Items.Clear;
  for iRole := low( TRole ) to Hi(TRole) do
  begin
    pComboBox.Items.Add( EnumAsText( iRole ) );
  end;
end;
在EnumToText中使用const数组而不是case语句的优点(显而易见的方法)是,如果扩展enum,编译器将强制您相应地修改函数。
组合框的ItemIndex对应于整数字段

您根本不需要TRole枚举。只需使用条目填充组合框,使其索引对应于数据库值(0=管理员;1=普通用户)。还将ComboBox的样式属性设置为csDropDownList

procedure PopulateComboBox(const cb: TComboBox);
begin
  cb.Clear;
  cb.Items.Add('Administrator'); // ItemIndex = 0
  cb.Items.Add('Common User'); // ItemIndex = 1
end;
现在,当您使用SQL请求获取数据时,您可以将Role列的值直接应用于combobox的ItemIndex属性:

Query.SQL.Text := 'select Name, Role from table where ID = :ID';
...
if Query.FieldByName('Role').AsInteger in [0..1] then
  RoleComboBox.ItemIndex := Query.FieldByName('Role').AsInteger
else
  raise Exception.Create('Role column value must be in range of 0..1');
在将角色保存到数据库时,您的操作基本相同。使用ItemIndex属性作为要保存的值:

if RoleComboBox.ItemIndex in [0..1] then
begin
  ...
  Query.SQL.Text := 'update table set Role = :Role where ID = :ID';
  Query.ParamByName('Role').AsInteger := RoleComboBox.ItemIndex;
  Query.ExecSQL;
end
else
  raise Exception.Create('Invalid role index');

快到了。。。问题是它需要在数据库中保存为整数。如果我想将它们另存为strings,您的方法是有效的。如果您使用组合框的ItemIndex属性,它是一个整数,与您的字段完全对应。因此,在这种情况下,我不会使用TDBComboBox来保存此字段,而是使用公共TComboBox并通过ItemIndex手动保存?啊,是的,我确实会这样做。您需要另存为字符串才能使用TDBComboBox。老实说,我倾向于不使用数据感知控件——我发现它们限制性太强了。好的,您必须自己处理数据库,但这是为灵活性付出的代价。
if RoleComboBox.ItemIndex in [0..1] then
begin
  ...
  Query.SQL.Text := 'update table set Role = :Role where ID = :ID';
  Query.ParamByName('Role').AsInteger := RoleComboBox.ItemIndex;
  Query.ExecSQL;
end
else
  raise Exception.Create('Invalid role index');