default vs custom using entity framework - c#

I've got a table of default templates. It's global to all users. If a user has no custom template, I want to pull the default. If a user decides to customize the template it should be saved in a customtemplates table - as opposed to the globaltempaltes table.
the custom table has all the globaltemplates fields plus a userid and an id relating to which global it is replacing.
To flesh this out a bit more, lets say there are 3 templates, and a user wants to customize template 2 only. I would normaly pull the whole globaltemplates table and whatever relates to the user in the customtemplates table. Then, in the class property I'd do something in the get like this:
MyTemplateA
get { return customtemplates.A ?? globaltemplates.A; }
Can I do this using straight ef4/linq without poco?
Would a partial class with some additional properties like the get above work?
Since i'm always editing only the customtemplates table (add/edit/delete) it doesn't matter which version of the template I pull. I guess it could get hairy figuring out if it's an insert or an update.

In my opinion it will not work as you expect because EF closely relates entity to table. You cannot have single entity mapped to two tables except very special situations like splitting or inheritance.
So if you have Template entity it can be mapped only to single table but you have two. What you can do is to use TPC inheritance where Template will be a base entity mapped to GlobalTemplates table and UserTemplate will be derived entity mapped to UserTemplates table. TPC (table per concrete type) is type of inheritance where table for derived entity contains all columns from table for parent entity.
But inheritance still has a few problems for your scenario:
Template is editable - if you want to have it read only you must correctly handle it in your application logic. Any changes to attached Template instance will be saved when you call SaveChanges on the context.
When you load Template you cannot directly convert it to UserTemplate to make it user specific. You must create new instance of UserTemplate and copy properties from Template to the newly created instance.

Related

Entity Framework database-first - dynamically adding table to model

I have tables with the same structure but with a letter prefix of every table.
For example:
A_Company, B_Company, C_Company
There is combo box from which the user can select A, B or C, and then the code saves data into the appropriate table.
How can I do this using EF database-first?
I solved this problem adding a column for code prefix and triggers on my base table company for insert update and delete.
As the other commenters have said, it would be much better to refactor the database to a single table. If you can't do that then the only other thing that I can think of is to have a class which will select the table for you.
I would create a new class which has the same properties as your company tables, and also has the descriminator property. This would then be used as the data source for your ui.
in this class you would have to code manually to draw the data from the correct actual table (and save to it) based on the value of the discriminator. This is fine if you have only a few tables, but as your number of identical tables grows large, this will become more of a headache.
It might be possible to have the base tables all inherit from a virtual base class which would help a bit - you could then create a dictionary which the base class could use to switch the final data source on the fly.
As a final thought have you considered:
1. Creating the master table as suggested by the other commentators as a single table and then having views for each company.
Creating the master table as suggested and then having code to create the individual tables from that one at some point prior to their use?

Flattening multiple tables to a single type

I'm trying to model a database currently using EntityFramework's Fluent Configuration. I cannot edit or otherwise control the database schema. The entity I am trying to model has a lot of look-up tables - for example, one property (it's name) has a whole table devoted to it with a name associated with an id (which is it's language). In other words, it looks a bit like this in the database:
Entity
string[] Names
Entity_Names
string Name
int LanguageId // 9 = English
However, I am trying to condense this into
Entity
string Name // I only want the English name
Using a SQL query, this would be pretty simple - but how can I do this via Entity Framework's fluent configurations? There are a lot more of these instances as well, but this is the simplest example I could come up with.
If you do manage to flatten the model this way, it's almost certainly going to be a read-only view of the data. There's no way for Entity Framework to know that a string property should be looked up in another table and replaced with an integer id.
So that leaves two options if you're okay with it being view-only. Write a database view that replaces the ids with the strings and build an entity for that view.
Or build entities that are compatible with the schema model and project the data into a dto.
The second approach is the one I'd prefer as it means you'd still have a compatible entity model if you do need to CRUD.

Add an extra column to my model in an .edmx file

I want to add an extra column, similar to a join to my model based on the ID. Is this possible?
For example:
ProductsModel
ID
DeliveryID
DeliveryModel
DeliveryID
DeliveryDescription
What I'd like to do is add the DeliveryDescription column to my ProductsModel in my .edmx file. I know its possible to add 3 property types (scalar, navigation, complex) are one of these the solution?
No. Default entities must exactly match your tables. There are situations where this is not the true but all involve advanced mapping features like splitting or inheritance. By looking at your tables neither of this is case.
What you are trying to do is equivalent to database view. It is possible in EF by either using QueryView or DefiningQuery. Both will result in new read-only entity type. To use these advanced features you must manually edit EDMX file (and in case of DefiningQuery you cannot use update from database any more because it would delete your changes).
You most probably need this for some data presentation so instead of modifying your mapped entities create a new class outside of EF just for presentation and fill it from entities.

Entity Framework 4 and SQL Server 2008 Multiple Possible Foreign Keys

I am trying to come up with a database design that would work with Entity Framework 4 Code First. Actually, I have no experience yet of EF4 Code First but as I understand it, if I write the code, it will create the database and tables.
The issue is this. There are various types of auctions, they all have some common fields and some specific ones. In the code I envisage having a base abstract class called Auction and subclasses like LowestUniqueBidAuction and EnglishForwardAuction etc.
Nothing surprising there. The problem is that I imagine the database structure to mimic this. I imagine an Auction table and a LowestUniqueBidAuction table and a EnglishForwardAuction table. In the Auction table I imagine a foreign key into one of these two tables for each row depending on the type of auction that that row is. I also imagine another column in the Auction table with the name of the derived auction table (such as EnglishForwardAuction).
The problem is that whenever I've ever created a foreign key I've had to specify the name of the foreign table into which the key points (which makes sense). In this case, however, there is one of many tables that the key could point. So there are many issues here. Firstly, I could simply not use a foreign key and just use an ordinary field, but then the database will not be able to maintain data consistency for me. The second issue is how will EF Code First handle this? In other words, how will it know that if I ask for all EnglishForwardAuction rows from the Auction table that it should look at the column with the table name and then join on the EnglishForwardAuction table to get the extra fields?
Has anyone ever faced similar issues?
Thanks,
Sachin
This problem is solvable in Entity Framework in a number of ways - read up on how EF handles inheritance and what strategies are available.
There are basically three strategies how to handle this:
(1) Table per Hierarchy
You have only one single table, that represents all possible sub classes. Of course, this means, several rows (that only exist in a given subclass) must be nullable, since they don't show up / don't exist in super classes or other subclasses.
(2) Table per Type
Each subclass gets its own table, and by default, the sub-types table shares the PK with the base classes' table - e.g. PK = 1 in Auction will also be PK = 1 in EnglishForwardAuction. So your subclass tables reference the base table - not the other way around.
(3) Table per Concrete Type
Each concrete subclass (your separate auction types) gets its own table, but that table contains everything - all the columns, from that specific type, but also its base type.
Read more here:
Inheritance in the Entity Framework
Inheritance and Associations with Entity Framework Part 1
Entity Framework Modeling: Table Per Hierarchy Inheritance
Entity Framework Modeling: Table Per Type Inheritance
Searching for Entity Framework Inheritance and/or one of these strategies will reveal a lot more hits, too - that topic is very well covered and discussed on the interwebs! :-)

Entity Framework - Can you map the result type of an imported stored procedure to a custom entity type?

I already have an entity model in a separate dll that contains various objects that I need to use. I don't really want to create or duplicate entities using the EF designer. Instead I would like to configure it so that when I call a stored procedure it will map certain columns to specific properties.
I know you can do something VERY close to this using a custom DataContext in LinqToSql. The problem is you can't assign columns to complex property types. For example: I might have a columns returned that contain the address for a user. I would like to store the address details for the user in an Address object that is a property of a User object. So, Column STREET should map to User.Address.Street.
Any ideas?
There are a couple of options here.
You can create a "Complex Type" and map that to the procedure result. However, you have to do that in your EDMX; it's not supported by the designer. Read this article for details. Note that Complex Types are not entity types per se, so this may or may not fit your needs. But you can find examples for stored procs which use "Address".
You can change the visibility of your procedure to private, and then write a public interface for it in any manually-written partial class file which does the mapping that you want. Or just overload the procedure.

Categories

Resources