Microsoft Lightswitch and Entity Framework Code First Inconsistency - ef-code-first

I've begun investigating Microsoft Lightswitch 2011 as a possible solution for developing quick "admin" apps for updating various databases - primarily those containing lookup tables or configuration data for internal corporate websites or applications.
I have a website that was developed using ASP.NET MVC. EF Code First was used in building out the data layer. Some of the relationships are many-to-many which EF CF handles by creating a join table with just two fields containing the primary keys of the two tables involved in the relationship. The primary key of the join table is combination of the two fields. For example, a document entity can have many categories and a category can consist of many documents. Three tables get created: Documents, Categories, and DocumentCategories. DocumentCategories only has two columns: DocumentID and CategoryID.
When this database is attached to Lightswitch as an external database, and a master-detail screen is created for the Documents table (and showing the related Categories), data can be deleted from and added to the related table (the join table) but not modified.
Investigation revealed that Lightswitch requires a join table in a many-to-many relationship to have its own primary key that is not a concatenation of the keys of the related tables. In other words the table must be of the format: DocumentCategoryID, DocumentID, CategoryID. If the join table is structured that way, it becomes possible to update the entries in the related table.
I know that I can work-around this by not updating records and simply deleting and re-adding them. That's not a big deal since 1) Lightswitch makes that easy, and 2) there's usually not wholesale changes in the related data. It goes against my sensibilities though of "what's right".
So at the risk of providing fodder for all the Microsoft tool haters, 1) is this just a case of Microsoft making a mistake and not being consistent or is there some other force at work here, and 2) is there a way to "fix" this without having to rework my ASP.NET MVC, EF CF app and changing the database structure?

1) LightSwitch works. Yes there are 'haters' but then there were haters when nail guns came out ( http://jhurst.blogspot.com/2011/01/nail-gun-or-hand-nail-your-roof-which.html ) The end user who is paying for our services will demand that we use tools that can reduce costs by 90%+
2) Using WCF RIA Services allows you to place a layer between whatever you have going on in your data layer and LightSwitch (see: http://lightswitchhelpwebsite.com/Blog/tabid/61/tagid/21/WCF-RIA-Service.aspx ) Only use the 'data source wizard' when it works for you. If it gives you any problems then a WCF RIA Service, that will only take you 5 minutes to code up, will resolve any situation because you are able to drop into procedural code to handle any transform you need.

Related

When creating a new Dataverse table, why does it come with automatic columns?

I am new to Dataverse, moving from the SQL Server world, and just created my first Dataverse table (Standard table). Upon creation, the table has lots of what I assume are automatically-added columns? These include "Owner", "Status", "Version Number". I come from the SQL Server background where new tables come "empty", with no columns. I do not think I need these automatically-added columns (this is just going to be a small log table that holds datetime, action, etc. columns).
Would it break anything if these automatically-added columns were deleted? Also, if anyone could provide information about why these columns are included, that would help. I have researched these questions online, but found very little. Thank you in advance.
They are standard, out of the box attributes that you can't remove.
You can change the Ownership within the Table Type to "Organization" when creating the table to remove the Owner however the rest are created as part of every table.
There is some high level detail on the docs
https://learn.microsoft.com/en-us/powerapps/maker/data-platform/entity-overview
Dataverse (earlier called as Common Data service) is Dynamics CRM under the hood. It’s a SaaS model CRM online software comes with some basic fundamental components.
When you create a table (entity) it comes with columns (attributes), relationships, views, forms, dashboards, etc.
The UCI model driven app can be made quickly to include these components with all CRUD operations without any code by doing simple configuration and customization.
To support these barebone functionalities - the necessary attributes like name, currency, statecode, statuscode, createdby, createdon, modifiedby, modifiedon and security implication fields like owner, owning business unit, owning team and change tracking & concurrency fields like row version, etc will be created.
You can keep them aside as they are part of platform and do your customization as you need.

SQL. Re: inner joins & foreign keys

Good day.
I have a basic question on SQL and table structure.
What we have now: 17 tables. These tables include 1 admin table. The other 13 tables are all branched off 3 "main" tables: customers, CareWorkers, Staff.
If I'm wanting to adhere to ACID ideology, I want to then create tables that each houses unique information.
My question is, and what I'm trying to wrap my head around, when I create each of these "nested-deeper" (not sure what to call it) tables, I simply do an inner join statement to grab the foreign key on my ASP.NET app correct?
First, inner join is how you get your tables "back together", and #SpectralGhost's example is how you do it. But you might want to consider doing it in the database rather than in your ASP code. The way you do that is with views. If you create a view (the syntax is CREATE VIEW and there are plenty of examples out there) then you can make the database schema as complex as you need to without making it hard to use in your ASP application. You can even make views updatable (you define an "INSTEAD OF" trigger, again, many examples if you search).
But you probably don't want to update a view, or a table, directly from your ASP code. You probably want to define STORED PROCEDUREs that update your data, and call those from your ASP code. This allows you to restrict access to your tables and views to read only and force any writes to come through a stored procedure you can control better. This prevents SQL INJECTION, making your ASP application much more secure. If the service account the application pool you ASP page runs under can pass raw queries to the database then any compromise can do tremendous damage to your database. If all it can do is execute a stored procedure where the parameters can be changed but not the functionality, they can only put some junk values in, or maybe not even that if you range check well.
The last bit of advice is that you are not preserving "ACID", you are preserving "NORMALIZED". It's definitely a tough concept to wrap your head around, here's a resource that helped me out a great deal when I was starting out. http://www.marcrettig.com/data-normalization-poster/ I still have a copy on my wall. You shouldn't obsess over normalization, but you should definitely keep it in mind and stick to it when you reasonably can. Again, there are numerous resources a search will get you, but the basic benefit is a normalized database is much more resistant to consistency problems, and is more storage efficient. And since disk IO is slow, storage efficient is usually query efficient too.
They are related tables. You should have at least one table with a primary key and often several that related back to that table from that table's foreign key.
TableOne
TableOneID
TableTwo
TableTwoID
TableOneID
TableTwo relates to TableOne via TableOneID. An inner join would give you where there are records in both tables based on your join. Example:
SELECT *
FROM TableOne t1
INNER JOIN TableTwo t2 ON t1.TableOneID=t2.TableOneID
Specifically how to do this in your application depends on your design. If you are using an ORM, then actual SQL is not terribly important. If you are using stored procedures, then it is.

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

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.

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

Resources