Join data in CQRS patterns from different microservices - join

I want to apply CQRS pattern in a project but i don't understand how can i join and denormalize data.
Consider a data model where there are 2 entities: Product and Store in a many to many relationship and an attribute named stock (the product quantity in a particular store) as a relationship attribute.
Consider also that I already created 2 microservices:
ProductService: responsible to handle CUD operations on products;
StoreService: responsible to handle CUD operations on stores. The entity ProductStore is managed by this service.
At this point, I want to create a third microservice that is responsible to join the data of ProductService and StoreService in order to retrieve all the available products. Here, CQRS pattern seems like the best solution: I will create a materialized view and I will synchronize it using domains events published by the other 2 microservices. Great!
And now the doubts.
Suppose the materialized view has the following columns:
product_sku, product_name, stock, store_name, store_address.
When I update a Product entity or Store entity there is no problem to sync the view because I already have data on it. But what about when I receive a ProductCreated event? This event has only information about product and nothing else, so stock, store_name, store_address will be NULL. How can I save this event in my view? Should i save incomplete data somewhere else and update my view when I will receive complete data?
Thanks!

CQRS , Event sourcing and Materialized view
Your are right, Generally CQRS , materialized view goes with Event sourcing pattern. Which means that we keep on adding our events into event store (this is single point of truth). We generate materialized view by scheduling the job that would read the data from event store and create/update materialized view or we can generate the materialized view following by event trigger. So when you would get store service event (that's probably after product event) then you know that's your last event for particular transaction and query event store to update materialized view and you will have all the data. In short keep dumping in event store and query at once your event store to update your materialized view. Adding event source itself can be complicated so don't over complicated if you can mange without it.
Your case
If you are not using event store then in your case you save the partial/incomplete information in the Materialized view and keep updating it when other inflight events arrive. You will have single reference/key against which you will be updating your data in materialized view. Since the whole system is eventual consistent you will have to manage how would you like to display incomplete (if you have to) data on frontend or you can flag it if you don't want to show (unflag when last event arrives and information is complete).
Materialized view

Related

Entity framework multiple DbContext in single execution

I have one master & detail in my 'db1' and there is one column named 'EntryByUserId' in master table.
User table is available in 'db2'.
When all the tables are available in one single database we can directly get user detail by using include function. But here my reference table is in another database so in my case user object will return null value. So anyone please help me to achieve this.
I have created multiple dbcontext in my project but don't know how to get this.
Below is the code we use when all tables are available in single database.
dbcontext1.tbl_Master.Include(m => m.tbl_Detail).Include(m => m.tbl_user)
.AsNoTracking().FirstOrDefault();
One option to accommodate this cleanly, especially for something as frequently accessed as a "User" reference for something like reporting on CreatedBy or ModifiedBy tracking on rows would be to implement a view within Db2 that lists the users from Db1. Then in your main application context you can map a User entity to the view rather than a table. I would put guards in your DbContext and entities to discourage/prevent modifications to this User entity, and leave maintenance of users to a DbContext overseeing the Db1 tables.
If this is something like a multi-tenant system with a system database for authentication and separate DBs per tenant which are tracking things like CreatedBy against records, I would recommend considering a system to inspect and replicate users between the auth database and the respective tenant databases. The reason for this would be to help enforce referential integrity for the data and the user references. The issue with the view approach is that there is no constraint available to ensure that a UserId reference actually corresponds with a row in the Users table over in the other database. It can be indexed, but not constrained so you have to handle the possibility of invalid data.

single view - page - showing data from a group of normalized of tables

What I hope is a basic question,
I am designing an MVC project with the entity framework and code first and in it has a number of normalized tables that later will make up a combined view.
For example say I have a table called JOBS. This table has foreign keys for a CUSTOMER table, a STATUS table, a JOBSTYPE table.
If I want a view (a page) that displays the job with the customer, its status and its jobtype how do I manage this outcome?
In other words if I want a page that shows the job, the customer and the jobs address (sourced from the address table - itself linked via a foreign key in the customer table) how do I do the view for this?
Further, with a focus on CRUD, If I want an update page how do I display a page that has text boxes to update things like the job's address or the status which are in different tables to the actual job table.... and to press a button on the page saying "update" and each table updating automatically..
Look forward to any help clearing the confusion...
Kind Regards
Simon
Just as the question, this answer is hypothetical as well. What you can do is have a look at your page design and figure out the columns/properties you want to show from multiple tables, you then create a ViewModel for this page, then you can write a LINQ projection query to bring the results as your viewmodel.
Another other option will be to use lazy loading all linked tables and render related entities, but this this approach you have to make sure that the EF context is not disposed till the whole view has rendered.
The ViewModel and Projection approach also works well with updates and your update action will take in your view model and translate back to EF entities for updating.
For translations from ViewModel to EF Model entities and vice versa you can use automapper

Core Data: Which record loads by default in core data if you do not specify which one?

I have a static table for settings where I want to pull some stuff from an entity in Core Data. The use case does not lend itself to a table of records as you usually see. Rather each row of the static table is really a field related to the user--as in a user profile. I have a feeling that in testing I may have created more than one record in the entity. I know there are programs that let you see the SQL lite database underneath, but my question assumes you do not have this tool and are relying just on Xcode.
My question is when you have more than one record in a Core Data entity/table, and you try to load data from the managed object context into a VC, one field into one element, what record is shown by default?
Related to this, if you don't know how many managed object or rows are in the database, is there anyway to specify which record you want since there are no auto ids as you would use in a traditional database?
The record that gets loaded from the fetch first. Depending on your sort that might be consistent or it might be random.

Persist different objects (types) as single object - CoreData - (Favorites example)

My question is how to implement this correctly and with good design.
I would use Core Data for this.
Problem description:
Let's suppose that we have two object types (classes) in the system, Location and Event. They are retrieved from webservice, and there is no need to persist it.
Any of these two kind of objects can be added (saved) to favorites and it should be persisted locally.
Additional requirements:
show and manage favorites - let say in FavoritesViewController (I would use here NSFetchedResultController)
display (cell) of favorites is different, according to favorite type (location or event)
in Location/Event details view controller, there will be an action to add/remove to/from favorites, and the state of that action should be set according to favorites existance
in the future, it can be another object type which can be added to favorites (for example, Drink).
I have a dilemma about the best way to implement this. Should I store locations and events directly as separate entities (model objects), and somehow retrieve it in a single fetch, in order to get and manage the list of favorites. Or, maybe use an interface/protocol (for example Favorable), and create and store Favorite objects, and each object which can be added to favorite should implement favorable and will be converted to Favorite object, but in this case, it will limit favorites to only attributes that Favorite object exposes.
You should make a simple Core Data model with the two entities. It is very straight forward. Your table view would have two type of cells (with different identifiers) that display the data as needed.
You can use these to entities (subclasses of NSManagedObject) throughout your app. You should perhaps persist them anyway (so they are available if the internet goes down and allow the user to continue working with them). The favourite instances can be marked with a BOOL property.
One design consideration, though: maybe you want to create an optional relationship between Location and Event. Some events might be tied to a particular location and you will need this info as well. With Core Data this is really easy to do.

Deleting Entities and its Navigation Properties

I have something like a Customer object with up to 50000 order in an ICollection<Orders>.
Assume the Custome being in the local cache, the orders not. How can i delete the Cutomer and all of its related orders without loading all of the Customer orders into the cache and marking them with setDeleted()?
What is the best practice here. I assume extending the public SaveResult SaveChanges(JObject saveBundle) method is the best way. Any other possibilities here on the client side like a flag delete_all_navigation_too()?
Thanks
I must suppose that you do not have and do not want cascade delete on your database. Personally, I'm "terrified" of deletes in general and try to avoid them. I prefer a soft delete (marking a record as inactive). But not everyone agrees or can follow suit
I would consider adding a Web API method (say "DeleteCustomerAndOrders") to your controller to do it. You can call any API method from your client, not just a Breeze method.
In recommending this, I'm assuming that this kind of thing is a relative rarity in your app. You don't need a general purpose deleter, a deleter that takes an array of parent object IDs, a deleter that will delete some child objects and not others, ... etc., etc.
Follow this path and you will have moved the problem from the client to the server. That's good: you didn't have to load the orders on the client. Now you have to get rid of them on the server. If you're using Entity Framework, you face the same challenge of deleting the orders without loading them. Check out Alex James' solution: Bulk-deleting in LINQ to Entities.
Simplest approach that I can come up with is to create a cascade delete constraint on the database so that when a customer is deleted all of its orders get deleted as well. Then simply delete the customer on the client and call 'SaveChanges'. In addition, since Breeze does not yet support client side 'cascaded' deletes ( we are considering this one), you will need to iterate over any client side orders that are already loaded and 'detach' them.

Resources