Entity Framework: Define a string computed Primary Key column in Data Annotations

Hello all, I am looking into Entity Framework for my main API project, where I am currently still doing the structure of my database. In order to make some data a bit more readable. I have decided to create a generate string primary key for this table. The Composite Key is defined by three variables, technically it only has to have two variables but I am picking three to make sure the variables itself is really unique. And it has to be structured like this: DexID-GRID-BreedableState(first letter) So let me give one example I have one row with the following: DEXID, GRID, BreedableState 25, 2, false The new composite Key has to be established like this then as an example: 25-2-f The thing is while I know you can set it a computed value like this in Entity Framework: [DatabaseGenerated(DatabaseGeneratedOption.Computed)] I do not know how to do set it to the way I want in the model. So can anyone help?
Table structure in ERD.
14 Replies
Munjakis
Munjakis5mo ago
Im not sure that i understood it well, but maybe something like this?
public class YourEntity
{
public int DEXID { get; set; }
public int GRID{ get; set; }
public bool BreedableState { get; set; }

// Computed composite key
public string CompKey => $"{DEXID}-{GRID}-{(BreedableState ? "t" : "f")}";
}

public class MyDbContext : DbContext
{
public DbSet<YourEntity> Persons { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure the composite key
modelBuilder.Entity<YourEntity>()
.HasKey(p => p.CompKey);
}
}
public class YourEntity
{
public int DEXID { get; set; }
public int GRID{ get; set; }
public bool BreedableState { get; set; }

// Computed composite key
public string CompKey => $"{DEXID}-{GRID}-{(BreedableState ? "t" : "f")}";
}

public class MyDbContext : DbContext
{
public DbSet<YourEntity> Persons { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure the composite key
modelBuilder.Entity<YourEntity>()
.HasKey(p => p.CompKey);
}
}
ThunderSpark91
ThunderSpark91OP5mo ago
Okay that seems really close to it.
Anton
Anton5mo ago
why? just use an actual composite key?
ThunderSpark91
ThunderSpark91OP5mo ago
It has to do more with what for data I am dealing without doing very long querry's. Not to mention this is a question I want to answered if I ever come to similar situation. Full disclosure this is a Pokemon Project, In the example instance I know I am dealing with a Cap Pikachu here (because the Standard Pikachu is 25-1-t), because that one is not breedable in game. I already use the standard table for the Species and Pokédex Number but I will have to subdidde while still keeping track of the Dex number. It has to do more with readablity and not constantly repeat three columns every time. If that is still better with performance, that I will gadly switch over to that option.
No description
Anton
Anton5mo ago
be sure to check the generated queries if you do that I suspect it will do everything on the client side, because it doesn't have access to the espression of that property there's a lib to help with expanding expressions like that in the query
ThunderSpark91
ThunderSpark91OP5mo ago
The First Program I am making myself as satrting point is ASP.NET API with public end points for other users and Private end points for my other applications.Do not know if need that part you just have described.
Anton
Anton5mo ago
don't you have a database?
ThunderSpark91
ThunderSpark91OP5mo ago
Yeah but am working code first sort, I let Entity Framework make my database as soon as I got the stucture done and the data I am going to insert. but after looking into this I might look into querries do you happen to know that name of that library?
Anton
Anton5mo ago
If you're going to do a query like .Where(x => x.ThatCompoundId == localVariable), it will do it on the client side (not in the database) I believe
Anton
Anton5mo ago
GitHub
GitHub - koenbeuk/EntityFrameworkCore.Projectables: Project over pr...
Project over properties and functions in your linq queries - koenbeuk/EntityFrameworkCore.Projectables
ThunderSpark91
ThunderSpark91OP5mo ago
Wat if I skip all this and just defined the Composite Key with multiple columns?
Anton
Anton5mo ago
check the queries with your approach first
ThunderSpark91
ThunderSpark91OP5mo ago
I see side question, there is something also i have been wondered how to set up a counted index. So my idea is the following I have One to Zero Many Table Relation between the Pokémon Forms and their Sub Forms. The Main Form itself does exist inside the SubForm table. But there would be a Index. This index is tracked by FormID and always counts starts from 0. If the Unique FormId, from the Primary Form get inserted the first time, aka this is the "default" form the Index of the FormID is 0. When that same FormID is inserted again that Formindex because the next counted number. Aka 1 in this case, the next FormIndex under that same after that 3. A new FormID if it has not been inserted gets an index 0. If the new FormID already exists it becomes the next possible number counted from the last indexed FormID. Just like I said the FormID index/count gets tracked per Unique FormID. I am trying to find a another more simpler solution that is more simpler than this to track the default state, at First I thought to just use Where my FormTypeID = 1 . This the Default State but considering there is certain other Pokémon that makes it bit more difficult( aka Forms and Minor Forms).. it makes a bit harder to do so.
No description
HtmlCompiler
HtmlCompiler5mo ago
not constantly repeat three columns every time
i guess it's in the eye of the beholder, but as for readability and usability i would prefer three columns having separated columns would be faster than having a single string columns, also because two of those would be numbers and so easily indexable you could keep a string column for this if it's more readable
Want results from more Discord servers?
Add your server