How to manage Constants in Application - constants

what is the best way to use Application Constants ?
What i usually do is create a separate table in database of constants and reference them as foreign key in other table.
In Java i use enum.
But how to keep a single place of authority for constants in application and what are the different ways i can do that(like table or enum).

What you described is a usual approach. You keep "constants" in the database layer and you mirror them in the application using enumerations. The only trouble is keeping them in sync. Following a strict process can help here. For example, you always update values on both levels immediately one after another, not interrupting the process for any purspose and checking in the changes immediately after it's done.
Another idea would to oly keep constants in the database. You also assign names to them. Whenever you use a constant in your application (by name) it is transparently loaded from the database. This way any change you introduce will immediately be seen by any user connecting to the database. The only error may be caused by an update happening in the middle of a transaction.

Related

Use Custom SQL OnModelCreating and/or immediately after

I wish to add custom SQL to my model creation.
(Right now I want to do that because I have used strongly typed ids in my domain model; so now ef core won't let me use .UseIdentityAlwaysColumn() on them. (As of 2021 this is a still-open issue). Even it it did, I also want to add specific Postgres sequence options).
A simple workaround is just a single line of Alter Table Alter Column... sql straight after the model creation.
I can see that MigrationBuilder.Sql() can do custom sql. So
Can ModelBuilder do custom Sql? I can't find it.
Alternatively, can I shoehorn a short Migration into the OnModelCreating()?
I wish to keep all the data definition code in sync in one place, not have most of it in OnModelCreating but bits of it elsewhere.
The short answer to both your questions is no. Or if I can use your phraseology, as of 2021 this is still not possible.
Seriously, EF Core is ORM, thus the main focus is on M(apping). Physical database attributes are not a priority, given the fact that one can use EF Core just to map to an exiting database (a.k.a. Database first). There is some limited support for indexes (not used by EF Core) and small set of other physical attributes, but no views, synonyms, triggers etc. The only SQL supported is in fact HasDefaultValueSql.
I wish to keep all the data definition code in sync in one place, not have most of it in OnModelCreating but bits of it elsewhere.
OnModelCreating is creating the mappings. At the time it is called, there is no real database involved. The model could be created for generating a migration, but that's only one (an completely optional) of the many usage scenarios. That's why you can't "execute" anything there. All you can do is to specify metadata (a.k.a. annotations) which then eventually are processed by the services responsible for different functionalities. Migration SQL generator is one of them, but it needs to understand these annotations when processing the corresponding operations. Which basically is the definition of supporting something or not.
In theory you could create your own annotations, provide custom metadata/fluent API for specifying them, but then you have also implement them for every database provider you want to support. This is a lot of work, practically impossible as every database provider implements the migration SQL generator for their specific attributes and DDL dialects.
So, whether what you wish it better or not, the practical approach would be to use what you got from ORM. Which currently is MigrationBuilder.Sql(). No more, no less. That's all. Period.
To recap shortly, if the questions are if there is some hidden "magic" way which you can't find, there isn't.

Strategy for deploying EF controlled Database

I have written an application using EF 6.0 in combination with an SQL Server Compact 4.0 Database. When a customer uses this application for the first time, it (the application) should create a database-file in a given path with some initital values. Also migrations should be allowed, for it is quite possible that the object model might change with future versions of the app.
Now I´m wondering what would be the best way to to deploy the DB on the users productive system. I could think of three ways:
I could create a DB-file with initial values and just copy it to the right place during installation process and use MigrateDatabaseToLatestVersionInitializer in the app.
In the DbContext-Constructors (I have two contexts) I could check for an existing DB-file and use different Database-Initializers accordingly. Like a CreateDatabaseIfNotExistsInitializer with a seed method that creates initial data if no fiel is found and a MigrateDatabaseToLatestVersionInitializer if the DB-file exists.
I could use the MigrateDatabaseToLatestVersionInitializer always and in its "Seed"-method check for existing table entries and create them if they are not present.
Which of these ways is to be preferred or is there a better way I didn´t think of?
It sounds like this is a desktop application so you might want to catch permissions errors about creating the database file at installation time (i.e. option 1) rather than run time, especially as in option 2 the database initialization is not an imperative command you're giving that you can put a try...catch around.
I don't think option 3 would work as the Seed method gets run after all the migrations, so surely the migrations will either have successfully run, in which case the tables don't need creating, or they will have failed as the DB doesn't exist and therefore your Seed method won't get run.

JPA multiple entities one table/view

I have been tasked with fixing a number of bugs on existing application that makes use of JPA (EclipseLink).
In this application it common for there to be multiple entities that indirectly share the same table via SQL views. As an example, I might have a entity called TEmployeeInfo and another entity called VActiveEmployeeInfo. While the first maps to a table directly, the second maps to a view of the same table as the first.
This seems like it would cause issues with caching as any updates using the first entity (table) would not be immediately available in the second (view).
Are my suspicions correct?
If so, what are some possible steps to correct this short of refactoring a large portion of the application?
If the same rows are mapped twice, then the cache can become stale if the objects are updated. You can have both classes use the real table, or perhaps use inheritance.
Otherwise, you can disable the shared cache of this class.
http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F

New entity ID in domain event

I'm building an application with a domain model using CQRS and domain events concepts (but no event sourcing, just plain old SQL). There was no problem with events of SomethingChanged kind. Then I got stuck in implementing SomethingCreated events.
When I create some entity which is mapped to a table with identity primary key then I don't know the Id until the entity is persisted. Entity is persistence ignorant so when publishing an event from inside the entity, Id is just not known - it's magically set after calling context.SaveChanges() only. So how/where/when can I put the Id in the event data?
I was thinking of:
Including the reference to the entity in the event. That would work inside the domain but not necesarily in a distributed environment with multiple autonomous system communicating by events/messages.
Overriding SaveChanges() to somehow update events enqueued for publishing. But events are meant to be immutable, so this seems very dirty.
Getting rid of identity fields and using GUIDs generated in the entity constructor. This might be the easiest but could hit performance and make other things harder, like debugging or querying (where id = 'B85E62C3-DC56-40C0-852A-49F759AC68FB', no MIN, MAX etc.). That's what I see in many sample applications.
Hybrid approach - leave alone the identity and use it mainly for foreign keys and faster joins but use GUID as the unique identifier by which i pull the entities from the repository in the application.
Personally I like GUIDs for unique identifiers, especially in multi-user, distributed environments where numeric ids cause problems. As such, I never use database generated identity columns/properties and this problem goes away.
Short of that, since you are following CQRS, you undoubtedly have a CreateSomethingCommand and corresponding CreateSomethingCommandHandler that actually carries out the steps required to create the new instance and persist the new object using the repository (via context.SaveChanges). I will raise the SomethingCreated event here rather than in the domain object itself.
For one, this solves your problem because the command handler can wait for the database operation to complete, pull out the identity value, update the object then pass the identity in the event. But, more importantly, it also addresses the tricky question of exactly when is the object 'created'?
Raising a domain event in the constructor is bad practice as constructors should be lean and simply perform initialization. Plus, in your model, the object isn't really created until it has an ID assigned. This means there are additional initialization steps required after the constructor has executed. If you have more than one step, do you enforce the order of execution (another anti-pattern) or put a check in each to recognize when they are all done (ooh, smelly)? Hopefully you can see how this can quickly spiral out of hand.
So, my recommendation is to raise the event from the command handler. (NOTE: Even if you switch to GUID identifiers, I'd follow this approach because you should never raise events from constructors.)

OO Databases that Pass by reference?

I have played with MongoDB a little and wondered is there every going to be, or can there even be a database which passes by reference or pointer.
E.g. I have a single user instance which can be put into multiple other arrays, if you change it once in one place it changes in all arrays.
I understand that in a database you don't want your data flung all over the disk but might we ever see one?
I would venture to guess you are accidentally creating multiple references when using MongoDB. There seems to be little value in creating a Graph for the database in which none of the nodes are shared.
I have used db4o and it will maintain a single instance of an object such that if you change it, then reference it from another Object the change will be "reflected." I put that in quotes because they should be the same object due to the way graphs work.