c# - Bitmask (flags) enum beyond 64 with bitarray with logical grouping stored in database -
the first answer question: what when bit mask (flags) enum gets large precisely i'm trying do, don't know how store in database using linq sql , tie users without creating 2 tables each thing/logical group.
this best explained via code (these linqpad friendly although incomplete):
// requirements: // 1) using linq sql // 2) track user's crud rights in different parts of application (parts referred below 'things') // example: thinga.create, thingb.read, thingb.update, thingc.delete // desired usage: if (user.isallowed(thinga.create)) { // allowed } else { // not allowed } // 3) allow more 64 'things' // 4) not want refer permissions using strings user.isallowed("create thinga"); // // scenario a: works, limited adding 60 'things' // example usage: // user bob = new user(); // var desiredpermissions = permissions.create | permissions.thinga; // permission = unique binary value combination of flags // if ((bob.permissions & desiredpermissions) == desiredpermissions) { // bob has permission create thinga [flags] public enum permissions : ulong { create = 1 << 0, read = 1 << 1, update = 1 << 2, delete = 1 << 3, // limited 60 'things' thinga = 1 << 4, thingb = 1 << 5 } // user model [table(name="users")] public class user { [column(isprimarykey = true)] public string fname { get; set; } [column] public permissions permissions { get; set; } public user() { } }
scenariob:
// // scenario b: work too, each new 'thing' need own flag enum list stored in own table (thingxpermissions), // table linking thingxpermissions.x users.id (userthingxpermissions) (yuck!) // avoid having change database structure when adding more 'things' in future. // user model [table(name="users")] public class user { [column(isprimarykey = true, isdbgenerated = true)] public int id { get; set; } private entityset<thingapermissions> userthingapermissions = new entityset<thingapermissions>(); [association(name = "fk_user_userthingapermissions", storage = "userthingapermissions", otherkey = "fk_user_id", thiskey = "id")] public ienumerable<thingapermissions> userthingapermissions { { return userthingapermissions; } } public ienumerable<thingapermissions> thingapermissions { { return (from in userthingapermissions select up.userthingapermissions).asenumerable(); } } public user() { } } [table(name="userthingapermissions")] public class userthingapermissions { [column(isprimarykey = true)] public int fk_user_id; private entityref<user> user; [association(isforeignkey = true, thiskey = "fk_user_id")] public user user { { return user.entity; } set { user.entity = value; } } [column] public thingapermissions thingapermissions { get; set; } } // thingapermissions [flags] public enum thingapermissions : ulong { create = 1 << 0, read = 1 << 1, update = 1 << 2, delete = 1 << 3 }
desired scenario:
// // desired scenario: psuedo code of i'd able do: // single permissions (crud) list // single||simple things list // single||simple table associating userx, thingx, permissionx // example usage: // user bob = new user(); // var desiredpermissions = permissions.create | things.thingz; // permission = unique binary value combination of flags // if ((bob.permissions & desiredpermissions) == desiredpermissions) { // bob has permission create thingz // missing link: combining enums , storing database linked user // e.g. // [table = "userpermissions"] // (user, thing, permission) // 1, thingz, create // 1, thingz, delete // 1, thingx, read // 2, thingz, read // 2, thingx, delete [flags] public enum permissions : ulong { create = 1 << 0, read = 1 << 1, update = 1 << 2, delete = 1 << 3 } [flags] public enum things : ulong { thingz = 1 << 0, thingy = 1 << 1, thingx = 1 << 2, thingw = 1 << 3 } [table(name="userpermissions")] public class userpermission { [column(isprimarykey = true)] public int fk_user_id; private entityref<user> user; [association(isforeignkey = true, thiskey = "fk_user_id")] public user user { { return user.entity; } set { user.entity = value; } } [column] public int fk_thing_thing { get; set; } private entityref<things> thing; [association(isforeignkey = true, thiskey = "fk_user_id")] public user user { { return user.entity; } set { user.entity = value; } } [column] public permissions permission { get; set; } }
additional code attempts:
not sure understand how flags work. reason you're using left shift operator enums exponents of following value.
the flag attribute let .net know value of enum multiples.
for instance if take thinga , thingb , add them (48)
console.write((permissions)48));
the value returned both thinga , thingb. able save single ulong
in database, code able figure out rest.
Comments
Post a Comment