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