What do I need to do in my database if I want my EF generated classes to look like this:
class A , class B : A , class C : A ?
Currently my DB tables look like this:
table A ID PK
table B ID PK and FK referencing table A ID
table C ID PK and FK referencing table A ID
thanks in advance
You need to specify this when generating your classes. Basically you choose a BaseType in the designer for class B and class C and remove the association. Here is an explanation how to do that (may differ slightly with different versions of EF)
http://msdn.microsoft.com/en-us/data/jj618293.aspx
What you want to do is known as "table per type" in case you want to look for more details online.
Related
Say I have a database setup with the following tables:
Project User Properties
------- ---- ----------
id id id
name name key
value
owner_type
owner_id
I want both the Project and the User entities to be able to have properties. The owner_type field on properties matches, for example, the tables names and the owner_id matches some row in the owner_type-table.
I have not been able to figure out how to do this in Entity Framework. I think I need to write some kind of custom relationship, but I cannot figure out how.
Edit:
I am not looking for a one-to-one or one-to-many relationship. I understand how that works. This problem is solvable with a pivot table for each Entity that can have Properties, but this is not what I want.
I am looking for a relationship that does something like this (perhaps using computed columns):
--- Select the properties for Project `10`
SELECT * FROM Properties WHERE owner_type = 'ProjectEntityName' AND owner_id = 10
--- Select the properties for User `2`
SELECT * FROM Properties WHERE owner_type = 'UserEntityName' AND owner_id = 2
I know that Laravel has these relationships in Eloquent, but I need them in Entity Framework. It is no problem that is not some default supported thing, but I want to be able to access the Properties using a syntax like this:
var project_properties = cx.Project.Where(p => p.id = 2).Properties;
Avoid mapping to the system tables that are specific to Sql Server database.
Properties belong to a class, so create the Class entity in your model, with an id and a name.
Use inheritance, create a base object for 'Project' and 'User', for example 'DbObject', that as attributes 'id' and 'name'.
Add a class_id field in your DbObject table as a foreign key on the Class Table.
Add a class_id field in your Properties table as a foreign key on the Class Table.
In your object model, class Properties has a navigation property on a Class.
Class
-------
id
name
DbObject Properties
------- ----------
id id
class_id class_id
name key
value
owner_type
owner_id
Project : DbObject User : DbObject
------- ----
(project (user
specific specific
attributes) attributes)
I am trying to make One To Zero One association between two tables in Telerik Data Access, but can't make it work. Here are my tables:
Student
Id (PK)
Name (string)
BackPack
Id (PK)
StuffInside(string)
StudentId (Unique, Foreign key)
StudentId in Backpack references to Id in Student. When I do the mapping for some reason Telerik is making it One to Zero Many. I need One To Zero One.
I assume you are using the Telerik Data Access Visual Designer to model your database? If so, in order to create one-to-one association you need to specify that the ID from one table (Students) matches the ID from the other table (BackPacks). This way each student will have exactly one (or zero) backpack. Please refer to this documentation article which demonstrates the approach.
If this is not applicable in your scenario and you have to match the Student ID to the BackPack StudentId to achieve the same effect you could create one-to-many association and then manually create the unique constraint on the database server side. Alternatively you could switch to Fluent Mapping which allows you to create custom indexes in you mapping.
I'm trying to port an existing application (using pure ADO.Net) to a new one using EF 4.3 Code First. It is worth mentioning that this is the first time I'm using EF.
Basically I have a suppliers table but with two specialization tables with attributes specific to each of the two types of suppliers.
Here is what the existing database looks like:
create table Supplier(
id_supplier int not null identity
--Bunch of other attributes
);
create table Individual(
id_individual int not null --not identity, gets the same value as the Supplier table
--Attributes specific to individuals
);
alter table Individual add constraint fk_individual_supplier
foreign key(id_individual) references Supplier(id_supplier);
create table Corporation(
id_corporation int not null --not identity, gets the same value as the Supplier table
--Attributes specific to corporations
);
alter table Corporation add constraint fk_corporation_supplier
foreign key(id_corporation) references Supplier(id_supplier);
So, as the tables show, a supplier can be either an individual or a corporation.
The existing application is like this:
abstract class Supplier with its attributes
class Individual deriving from Supplier with its additional attributes
class Corporation deriving from Supplier with its additional attributes
The Ado.Net code currently works receiving Supplier objects, generating records on Individual table if the object passed is of Individual type or Corporation table if the object passed is of Corporation type.
So, every record on Supplier will have a matching one on either Individual or Corporation. Also, Individual and Corporation tables does not have foreign keys to any other table of the database. Instead, the relations are all with the Supplier table. The table generating the ID is Supplier.
How can I map this with Code First?
At first I thought about keeping my structure, I mean, Supplier abstract class and Individual and Corporation deriving from that. Because I need Entity to insert on Supplier table first (generate identity field), it seems that both Individual and Corporation model classes would be mapped to Supplier table.
But how would it be possible for it to receive the abstract class and insert on either one of the specialization tables depending on the type? I don't think this is possible without custom SQL which makes me think my approach is wrong.
Thanks in advance for helping.
This sounds like "table per type" inheritance (TPT). With TPT there is a base table with columns that are common for all derived types and tables per derived types with type-specific columns. Entity framework supports this model. See this excellent blog post for examples how to do it both with data annotations and fluent mapping.
I have two tables like this:
Table1(id, name)
Table2(id_of_table_1, code)
I don't need an entity for Table1 or Table2, but one entity for both together:
class Merge{
public virtual long id{get;set;}
public virtual string name{get;set;}
public virtual string code{get;set;}
}
How can I load the tables to the edmx so that they will considered as one?
I don't have any control on the database and I can't create tables or views.
You are looking for advanced mapping called Entity splitting.
I think this is what you're lookig for: How to: Define a Model with a Single Entity Mapped to Two Tables
In short, you need to do this:
Add the two tables as two separate entities to your model
Cut the scalar values from the Table2 entity to the Table1 entity
Delete the Table2 entity
In the Table Mapping options of the Table1 entity, map the Table2-fields to Table2
For a more detailed explanation, you can have a look at this blog post.
Create a function inside your Merge class that writes the properties of your class to the appropriate Table1 and Table2 EDMX objects. Your Merger class should have references to those EDMX objects as internal variables. So this class is like a wrapper for your 2 table objects.
I have two objects (class, student) in a database with a many to many relationship (using a simple junction table). I've figured out how to correctly add new objects to tables, and now I'd like to delete an object.
I've been trying the following:
// (a classobj with id==1 does exist)
ClassObj cl = (from c in entities.ClassObjs where c.ClassID == 1 select c).First();
entities.ClassObjs.DeleteObject(cl);
entities.SaveChanges();
Which gives the error:
"The DELETE statement conflicted with the REFERENCE constraint \"FK_JunctionClassObjsStudents_Students\".
Where JunctionClassObjsStudents is the name of the junction table which creates the many to many relationship between classes and students tables.
What do I need to do? Thanks for your help!!
One solution is to put a cascade (or SET NULL) on the FK and then regenerate your entity model.
Assuming I have understood you correctly (and that is a big assumption)...
Class Table -> Class_Student_Junction Table <- Student Table
It seems to me that you would need to do this in two steps. The problem in my mind is the Junction Table you made, which has constraints. Without putting it into code I would say...
Step 1: Note the Key of the Class you want to delete
Step 2: Delete all from the junction tables where the foreign key for the classes equals the class from step 1.
Step 3: Delete the class record from the Classes table. There should be no key violations in that order.
You have to go through each StudentObj that references this ClassObj and remove the reference. This is necessary to maintain referential integrity.