Entity Framework / Database design - Updating data but keeping links to previous data - asp.net

I've learning ASP.Net and Entity Framework 4 by a practical example. To trial this, I'm using the example of User sending in devices for Repair. They create an account online, add in a set of Details (address, phone, fax etc), and create the return form (RMA) online.
The concept I am struggling with, is assigning Details to the Returns. A Return has a set of Details, one for contact, delivery and billing. These can be foreign keys to the Detail table, as shown below.
The problem is, that if a User edits their Details online, it will update the Details used on the Return. This is not the desired behaviour. The Return should uses the Details which were available at the time it was created.
The question is, how do you make the entity framework create a new Detail object, instead of updating the existing one. That is if the user updates Detail 23 with a new postcode, Detail 23 is not changed, instead a new Detail is created (i.e. 45). Detail 23 is removed from the User, and the new Detail 45 is added to the User. Whilst an existing RMA using Detail 23 is unaffected, meanings if you query the RMA you get the details which were supplied at the time it was created.
If on reading this question, you think the concept is flawed, and instead the DB should be designed differently (i.e. copying Detail data to columns in RMA table, or adding in a form of composite key to Detail table to create a history of revisions). I'm happy to listen to those wise words as well.

If you have complex data editing rules that are outside of the realm of basic CRUD, then you essentially have two choices with Entity Framework.
Give up on simple data binding and build your special handling into a business rule layer that sits between your GUI and your data layer (EF).
Give up the simplicity of a thin EF layer and put your special data handling rules into stored procedures and then set the CRUD procedures in your EF model to the stored procs you've defined.
Either way, you are making a compromise because no ORM, EF or otherise, can accomodate both "codeless" databinding and non-trivial CRUD processing. Pick the approach that suits your project and perferences the best. Some people can't live without databinding, some can't live with it. Some love stored procs and others loath them.

Related

Audit trail for established Access database

Good Evening all
I have inherited an Access database that is now running on Access 2010, there is currently no Audit trail for this dB and it's quite important that it has one.
I've read various articles that suggest a fairly neat solution based on calling a code module on an update event. However this involves editing every field in the dB to add a tagged property. The database isn't massive compared to some but going through maybe a hundred forms with between 5 and 50 fields on these form. Is there a method by which I could tag all the fields at once or maybe even another methodology
I was thinking of building a form users can fill in then an administrator does whatever is required at table level fills in their part of the same form, the data being appended to an audit trail table, seems a fairly unsatisfactory solution if this could be taken care of automatically ?
Any ideas

How to combine using Membership API with own application related data?

Designing a new application in asp.net 4 I have to make a decision how to use a MS SQL Membership API along with my own data in the MS SQL data base. Firstly I need to store and access user profile data in more flexible manner then the Profile provider supports. Secondly I would like to link other user related information (e.g. Orders).
No matter where you store your aspnetdb tables (in the separate data base or in the same data base with your data), the problem stays how to keep your data synchronized.
After a research I see the following relevant options:
1. Foreign key UserId from asp_Users (suggested in this tutorial).
2. No foreign key - use transactions (suggested here).
3. No foreign key - use customized AccountController (whatever it is, suggested here).
4. Additional table which links Membership UserId (uid) with custom UserId (int).
5. ...
On the one hand I like the first solution as it is quite straightforward and is suggested in an official asp.net tutorial.
On the other hand opponents note quite reasonably that using foreign keys breaks the general idea of providers which are supposed to help separating concerns and to be interchangeable. But unfortunately they do not go much into implementation details so it is not really easy to estimate those suggestions in terms of relevance and ease of implementation.
So what is the best option to approach this? Furthermore how would the implementation look like? Would it be enough to use just additional ADO.NET or LINQ etc code or is it worth implementing a custom Membership and/or Profile Provider?
Thank you in advance.
The first is the simpliest approach. Add the GUID of the user as a foreignkey in the related tables (f.e. Ordered_by). I don't see where it breaks separating concerns. If you want to keep the order-record in database, you also have to keep the user who has ordered, that makes perfectly sense.
I have used option 4 successfully in my current application. I've created a table aspnet_UserID with idUser int as primary-key and fiUser(the GUID of the aspnet_Users) as foreign-key. Here is the model:
(Note: User is the standard aspnet_Users table created via aspnet_regsql.exe and aspnet_UserId is my custom table that maps every Guid with my int-ID)
Now i'm storing only my idUser as FK in all related tables (like in your Order-Table). That has the advantage of less storage and more readable UserID's(i could never remember a GUID). Maybe it's somewhat more separated with this "wrapper-table" but that was not my main intention.
You can change the delete-rule on your foreignkeys if you want to control the behavior. Set it to Cascade if you f.e. want to delete all orders that were ordered by the user you're deleting or set it to no Action if you want to keep this order.
I can't suggest any alternatives for the Profile question because you haven't mentioned what you mean with "need to store and access user profile data in more flexible manner then the Profile provider supports".
You should consider writing your own custom membership provider that uses the tables/data as per your need (instead of using ASP.NET provided schema).
See this MSDn sample (schema, code) for writing a custom provider - this sample uses OLEDB to access database. Yet another sample is here - it uses active directory as a store.

ASP.NET Dynamic Data: Access rights only to specific rows

I want to use ASP.NET Dynamic Data for my next project, but there is a problem a can't manage to solve. In the database we manage authorization on a per-row basis. For example no user is permitted to see all rows of the Contracts table. So there is a Many to Many Relationship between Contracts and Users. So everytime Dynamic Data performs a Select to show all Contracts it has to look into the ContractUsers junction table to see what contracts the current user is permitted to see (filtered by UserID which will be stored in a session variable). Of course these junction tables should be invisible to the users.
By default Dynamic Data returns all rows of a table, so is it possible to customize this behaviour for every query the user performs?
I want to use Dynamic Data together with LINQ to SQL but if this task would much easier to accomplish using Entity Framework I would look into that too.
Thanks for your help and time.
Implementing such a solution in Dynamic Data it will probably require the creation of a custom Entity Template; not really easy but once done it will not require the creation of custom pages just the editing of the page templates.
I think it will be really usefull to check the excellent work on DD done by S.J.Naughton and presented on his blog.
Greetings, F.
You should not use dynamic data because you need full control over querying and manually write all linq queries to add your data level security. If you still insist on dynamic data be aware that you will still write most of pages yourselves and you will only use dynamic templates. You will have to manually define ever data source and correctly pass where condition to filter results based on logged user.
In addition linq-to-sql is not able to hide junction table and entity framework is able to do that only if junction table contains just two FKs for many-to-many relation. If this table contains any other column you want to use in the application you will have to map it as any other entity and dynamic data will show it as an entity.
Dynamic data are technology for quick creation of simple application where you need to provide access to database through web interface but what you describe is not a simple scenario. You need per record authorization which can differ among entity types.

Create new database programmatically in Asp.Net MVC application?

I have worked on a timesheet application application in MVC 2 for internal use in our company. Now other small companies have showed interest in the application. I hadn't considered this use of the application, but it got me interested in what it might imply.
I believe I could make it work for several clients by modifying the database (Sql Server accessed by Entity Framework model). But I have read some people advocating multiple databases (one for each client).
Intuitively, this feels like a good idea, since I wouldn't risk having the data of various clients mixed up in the same database (which shouldn't happen of course, but what if it did...). But how would a multiple database solution be implemented specifically?
I.e. with a single database I could just have a client register and all the data needed would be added by the application the same way it is now when there's just one client (my own company).
But with a multiple database solution, how would I create a new database programmatically when a user registers? Please note that I have done all database stuff using Linq to Sql, and I am not very familiar with regular SQL programming...
I would really appreciate a clear detailed explanation of how this could be done (as well as input on whether it is a good idea or if a single database would be better for some reason).
EDIT:
I have also seen discussions about the single database alternative, suggesting that you would then add ClientId to each table... But wouldn't that be hard to maintain in the code? I would have to add "where" conditions to a lot of linq queries I assume... And I assume having a ClientId on each table would mean that each table would have need to have a many to one relationship to the Client table? Wouldn't that be a very complex database structure?
As it is right now (without the Client table) I have the following tables (1 -> * designates one to many relationship):
Customer 1 -> * Project 1 -> * Task 1 -> * TimeSegment 1 -> * Employee
Also, Customer has a one to many relationship directly with TimeSegment, for convenience to simplify some queries.
This has worked very well so far. Wouldn't it be possible to simply have a Client table (or UserCompany or whatever one might call it) with a one to many relationship with Customer table? Wouldn't the data integrity be sufficient for the other tables since the rest is handled by the relationships?
as far as whether or not to use a single database or multiple databases, it really all depends on the use cases. more databases means more management needs, potentially more diskspace needs, etc. there are alot more things to consider here than just how to create the database, such as how will you automate the backup process creation, etc. i personally would use one database with a good authentication system that would filter the data to the appropriate client.
as to creating a database, check out this blog post. it describes how to use SMO (sql management objects) in c#.net to create a database. they are a really neat tool, and you'll definitely want to familiarize yourself with them.
to deal with the follow up question, yes, a single, top level relationship between clients and customers should be enough to limit the new customers to their appropriate data.
without any real knowledge about your application i can't say how complex adding that table will be, but assuming your data layer is up to snuff, i would assume you'd really only need to limit the customers class by the current client, and then get all the rest of your data based on the customers that are available.
did that make any sense?
See my answer here, it applies to your case as well: c# database architecture

Use ASP.NET Profile or not?

I need to store a few attributes of an authenticated user (I am using Membership API) and I need to make a choice between using Profiles or adding a new table with UserId as the PK. It appears that using Profiles is quick and needs less work upfront. However, I see the following downsides:
The profile values are squished into a single ntext column. At some point in the future, I will have SQL scripts that may update user's attributes. Querying a ntext column and trying to update a value sounds a little buggy to me.
If I choose to add a new user specific property and would like to assign a default for all the existing users, would it be possible?
My first impression has been that using profiles may cause maintainance headaches in the long run. Thoughts?
There was an article on MSDN (now on ASP.NET http://www.asp.net/downloads/sandbox/table-profile-provider-samples) that discusses how to make a Profile Table Provider. The idea is to store the Profile data in a table versus a row, making it easier to query with just SQL.
More onto that point, SQL Server 2005/2008 provides support for getting data via services and CLR code. You could conceivably access the Profile data via the API instead of the underlying tables directly.
As to point #2, you can set defaults to properties, and while this will not update other profiles immediately, the profile would be updated when next it is accessed.
Seems to me you have answered your own question. If your point 1 is likely to happen, then a SQL table is the only sensible option.
Check out this question...
ASP.NET built in user profile vs. old stile user class/tables
The first hint that the built-in profiles are badly designed is their use of delimited data in a relational database. There are a few cases that delimited data in a RDBMS makes sense, but this is definitely not one of them.
Unless you have a specific reason to use ASP.Net Profiles, I'd suggest you go with the separate tables instead.

Resources