Newbie question: Suppose I have a database table and would like to expose some basic methods like Add/Update/Delete through grains.
1) Should the grain be the table, or the individual rows?
2) If the table is represented with grains as individual rows, how do I create a master grain that can find the right grain to update?
Thanks
There is no reason that an Actor (grain) should be a one-to-one relationship with your table. If that is the case, just use entity framework and be about your day.
However there comes a point where it is worth it to realize complicated business logic using domain models for your company. That is IMO when a grain becomes pricesless. So I would make a grain per domain entity (model, row in table).
If you need to update a user, and a user is addressable by userId why not have...
var userActor = grainClient.GetGrain<IUser>(userId); // No need to have a lookup table here!
await userActor.Update(userUpdateModel);
If you do need to index on something, entity framework will do a bangup job.
// Entity framework repository
var userId = await _context.Users.Where( u => u.email == email ).Select( u => u.userId ).SingleOrDefaultAsync( )
// NOTE: you can use the userRepository to update the user directly, but that ignores
// business logic. Instead, the IUser grain implements business logic! Now you have
// a clear separation of responsibilities and layers.
var userActor = grainClient.GetGrain<IUser>(userId);
await userActor.Update(userUpdateModel);
Grains typically map to application entities, and in most cases that means they correspond to individual rows in a typical DB table. However, there are also cases where an entity is backed by a table as part of its state.
For example, a user is naturally represented with a grain as in the examples above. At the same time, as part of the user's state you might want to keep a set of related records like user purchase history. Those records will most likely be in a different table than user profile details.
So, in general grains naturally map to rows, but in the end it's up to the application developer to decide in each specific case.