ORM additional computed column in some scenarios? - c#

I am using the latest version of NHibernate, and I recently stumbled upon an interesting problem.
Let's say I have a table called Profile, and I want to receive a list of all my profiles. However, with it, I have a computed column called CanDelete which prohibits the profile from being deleted if (for instance) it is in use.
However, this CanDelete computed column is not part of my entity and I don't want to pollute the entity when I only need the CanDelete value in this scenario - and computing it individually for every profile is too slow.
Is there a way in NHibernate to execute some query and fetch the rows of that query as objects, but then somehow fetch an additional computed column as well?
Let's say I am using an N-tier architecture. All the way in the presentation layer I need a list of all profiles (and for each profile, whether or not I can delete it). How would my Business Logic Layer and Data Access Layer look like?
Right now in my repository I have a GetProfiles method and then a CanDeleteProfile method that I run for every profile fetched. But like I mentioned above, it is simply too slow. I could make a GetProfilesWithCanDeleteStatus method, but that would require me to create a specialized entity with that computed column on it as well.
What are your suggestions on how to architect this in a proper way when I don't want to hit O(n^2) performance in my profiles list? I would like to avoid the n+1 problem.
I am not necessarily looking for an NHibernate solution (I tagged NHibernate because it might have some specific tools for this kind of thing), and general solutions for other ORMs are welcome.

I have an idea that might be good for you, but it won't be a perfect one since each way you design your program has it's downsides.
I suggest you change the definition of that column CanDelete so it would be just like any other column in that entity (not computed at run time) and of type Boolean, but without damaging the requirements.
By doing so it would be like any other simple Select from the db - which is very quick.
Now, the tricky part is to insure that the column would indicate (at any time needed ) if it is been used or not (and if it can be deleted).
because I don't know the way you compute if Profile entity is been used (and can be deleted) it's difficult to tell how to design the DAL and BL exactly, but the guideline is :
in every other place you change a state in DB (of that entity or other) that might change the column CanDelete you encapsulate with a function to compute that value again to validate it's state and change it if needed.
If you insure that every time you change in BL one of the columns which CanDelete is computed from than you insure that the column CanDelete is always true indication.
The downside for this approach is :
1. It opens a place for mistake of a programmer not using the encapsulated function when needed.
2. It takes an assumption the this app is the only one changing this db.
3. You have to be careful from inserting raw data from an Management studio or script.
I Hope it's good for your BL.

Related

Better solution for updates with Dapper in ASP.NET Core

Let's say we've got a type Book with ten properties. This type is a representation of the table in database.
What's the best solution to update such a type? I've used repository pattern where I got update method that take Book type and updates all its fields.
So when I want to update a Book, I'm getting it by Id from database, update fields I want (I can update 1, 2 or all its fields) and then invoke Update method on repository.
My friend by contrast tells that we should update only the fields we want, so for example if i only want to update field bookTitle I should create method in repo UpdateTitle etc.
What the best solution? To be honest I see one method in repo update with all fields much better than multiple methods to update some parts/ones properties.
Dapper do not generate queries for you. You write the query and pass it to Dapper. Dapper do not track your types. You maintain the track of changes. Dapper just executes what you passed in and maps the result with your type/poco/entity/class whatever if applicable.
That said, how to update selected fields/columns? question is out of frame.
Now about other question — what approach to be taken? Both the approaches you mention have their own pros and cons.
Remember that, early optimization is root of all evil. Dapper is simple; keep it simple. Update entire type to begin with. Over the time, if you face critical performance issues AND you are sure the issue is due to updating all the fields, go ahead and optimize the query (or write new one) to update selected fields.
This will save you on efforts — will help improve performance if needed -- will keep the things simple.
Dapper itself doesn't support Tracking of database entities, there are ORMs that does that (e.g. Entity Framework)
Tracking allows you to load database objects into model class instances, once these are updated in code, you can save changes into the database, the generated query will update only the changed fields, as said, this is not supported in Dapper.
If you just use Dapper, I would recommend to keep it simple, save the whole updated object and consider changing that method if you have performance issues.

Is it possible to use Entity Framework and keep object relations in the code and out of the database

I'm having a hard time just defining my situation so please be patient. Either I have a situation that no one blogs about, or I've created a problem in my mind by lack of understanding the concepts.
I have a database which is something of a mess and the DB owner wants to keep it that way. By mess I mean it is not normalized and no relationships defined although they do exist...
I want to use EF, and I want to optimize my code by reducing database calls.
As a simplified example I have two tables with no relationships set like so:
Table: Human
HumanId, HumanName, FavoriteFoodId, LeastFavoriteFoodId, LastFoodEatenId
Table: Food
FoodId, FoodName, FoodProperty1, FoodProperty2
I want to write a single EF database call that will return a human and a full object for each related food item.
First, is it possible to do this?
Second, how?
Boring background information: A super sql developer has written a query that returns 21 tables in 20 milliseconds which contain a total of 1401 columns. This is being turned into an xml document for our front end developer to bind to. I want to change our technique to use objects and thus reduce the amount of hand coding and mapping from fields to xml (not to mention the handling of nulls vs empty strings etc) and create a type safe compile time environment. Unfortunately we are not allowed to change the database or add relationships...
If I understand you correct, it's better for you to use Entity Framework Code First Approach:
You can define your objects (entities) Human and Food
Make relations between them in code even if they don't have foreign keys in DB
Query them usinq linq-to-sql
And yes, you can select all related information in one call.
You can define the relationships in the code with Entity Framework using Fluent API. In your case you might be able to define your entities manually, or use a tool to reverse engineer your EF model from an existing database. There is some support for this built in to Visual Studio, and there are VS extensions like EF Power Tools that offer this capability.
As for making a single call to the database with EF, you would probably need to create a stored procedure or a view that returns all of the information you need. Using the standard setup with lazy-loading enabled, EF will make calls to the database and populate the data as needed.

Batch update for RIA in SL5

c#
I need to update 4 objects (entities) that exits on a observableCollection.
if they are not bound to the view (UI)
What's the best way or How they should be updated using RIA?
I would not like to create 4 trips to the database.
Would this gerenate 4 sql update commands?
What about if there is a time frame while the User decides what to change, could be other user changing one of the entity. if so what?
Any links I could read related to these questions ?
thanks in advance
should at least know what kind of update you need to do, basing on your question I'm just assuming that you need the user to change some arbitrary values on some entities, so, no "optimizations" and Group update can be done.
The domaincontext will keep track of your changes and send them as a whole in single Changeset.
The number of trips that you'll do to the database it's not related to WCF Ria services, rather it's a feature of your data layer, however, if you are using an ORM like nHibernate take a look at it's batchsize, or for EF take a look at his extension: http://weblogs.asp.net/pwelter34/archive/2011/11/29/entity-framework-batch-update-and-future-queries.aspx
Normally yes. Any out of the box data layer solution I know of, will generate 4 distinct updates
this is known as Concurrency. Again, is something that you should manage at your data layer. Raising an exception if other user have changed that row is a reasonable way in most case
take a look at this http://blogs.infosupport.com/optimistic-concurrency-with-wcf-ria-services-and-the-entity-framework/
I suggest you to reformulate your question into more specific arguments. Actually it's too wide, each point requires analysis of your needs and it's impossible to indicate a way.

View using same type as Table

I have a table that used throughout an app by Entity. I have a view that returns an identical column set, but is actually a union on itself to try to work around some bad normalization (The app is large and partially out of my hands, this part is unavoidable).
Is it possible to have Entity 4 treat a view that is exactly like a table as the same type, so that I can use this view to populate a collection of the same type? This question seems to indicate it is possible in nhibernatem but I can't find anything like it for entity. It would be an extra bonus of the navigation properties could still be used to Include(), but this is not necessary (I can always manually join).
Since EF works on mappings from objects to database entities this is not directly possible. What you need is something like changing the queried database entity dynamically, and AFAIK this is not possible without manually changing the object context.
For sure the EF runtime won't care as long as it can treat the view as if it was completely separate table. The two possible challenges that I forsee are:
Tooling: Our wizard does allow you to select views when doing reverse engineering (i.e. database-first). Definitively if you can use 'code first against an existing database' you can just pretend that the view is just a table, but you won't get any help scripting the database creation or migrations.
Updates: in general you can perform updates for a view setting up store procedure mapping (which is available in the EF Designer from v1 or in Code First starting in EF6). You might also be able to make your view updatable directly or using instead off triggers (see "Updatable Views" here for more details). If I remember correctly the SQL generated by EF to retrieve database generated values (e.g. for identity columns) is not compatible in some cases with instead-off triggers. Yet another alternative is to have your application treat the view as read-only and perform all updates through the actual table, which you would map as a separate entity. Keep in in mind that in-memory entities for the view and the original table will not be kept in sync.
Hope this helps!

Maintain entity data model when column is removed from database that is used many places?

Assume that I have a entity data model I generated from my database. I use one of the columns throughout code in many places, but one day I decide that I don't need this anymore, so I remove it from the database and the places in code that reference this property from the entity data model are now broken. Is the only solution to this is to go to each place and fix it or are there any strategies or tools that can assist in scenarios like this?
This question is only practical for applications that haven't been released yet. If an application has been released and this column already exists, it would not be removed or deleted. Existing customers may be depending on that column for data, it may be tied to application logic etc. For compatability reasons, it wouldn't be removed.
If this is pre-production application (pre 1.0 release), any ORM solution should be able to recreate the logical and conceptable model(s) after the physical column in the database has been removed. At that point, there may be some cleanup in the other layers of the application (UI, business, etc) that reference conceptable model in some fashion. For example, the UI may need to be updated to remove the display of that data. That would require some manual effort.
In general, it is better to keep it unless the application is in the early stages of development.
As such, you haven't specified about data in column and need for removing it, so we have to talk in general terms.
If you can remove the column from database and yet has used it in many places at code then probably its computed column - In general, it means you can derive the same information from other data-points. So in your entity model, you should stop mapping the column to the database and rather replicate the logic in the code to compute meaning-full value for the property. Or you can create a view over the table and compute the column at database side and map your entity to the view instead of table.
In case, the column is not computed then removing the column from database means loss of data. And if that is acceptable then it essentially indicates the change in underlying business model where that data point become irrelevant. You have two choices here -
Go for it and change your code for not to use this property - it essentially means that you will adjusting your code for business model/process change that you have to eventually do at some time.
Keep the column in database for some time but have a meaning-full default value. Mark the entity model property obsolete so that it will start giving warning. Take your time to make code changes, ultimate aim is to remove the property usage over a time and then remove the database column.

Categories

Resources