Similar Columns Relation in Entity Framework - c#

I use Entity Framework 4 on C# Winforms.
I have a SQL Server database with 2 tables like this:
Users table:
UserId (int) (PK)
UserName
Products table:
ProductId (int)(PK)
ProductTitle
UserId1 (int) (foreign key referencing `UserId` in `Users` table)
UserId2 (int) (foreign key referencing `UserId` in `Users` table)
I am modeling SQL Server database in my C# project with Entity Framework (including foreign key columns in model).
Then I get records with this code:
Entities dbEnteties = new Entities();
dbEnteties.ContextOptions.LazyLoadingEnabled = false;
var dbe = dbEnteties.Products.Include("Users");
var result = dbe.ToList();
When I get records from database I see that the UserId1 field has data but UserId2 field is Null.
What's wrong with my C# code? And how can I solve this problem?!

It's perfectly okay for you to have two foreign keys in the Products table pointing to the Users table. I do this all the time, and your reason for doing it is fine.
Since you have turned Lazy Loading off, you need to explicitly ".Include" the navigation properties if you want the query to automatically load them. You're going to have to figure out what the names are for the navigation properties that Entity Framework created automatically for you. I'm assuming you are using the "Database First" model. If that's the case, then double click on your .EDMX file and look at the Products table. You should see a section there called "Navigation Properties". They might be called "User" and "User1". If this is the case, then you need to do the following. Since you have two separate relationships between the tables, you will need two separate ".Include" statements:
dbEnteties.Products.Include(product => product.User);
dbEnteties.Products.Include(product => product.User1);
(Make sure to include using System.Data.Entity; at the very top of your file, otherwise the lambda syntax will not work.)

Related

How to select data from entity framework without selecting its icollection(foreign table)

I am using C# to select data from my database. Now i have two table, the first one is aspnetuser, the second one is aspnetuserroles, the aspnetuserroles have the foreign key linkage with aspnetuser table, when i perform the following query
db.AspNetUsers.ToList()
the aspnetroles data will appeared in the aspnetusers data. This will cause my datatable unable to display its data because datatable expect one value in one column parameter. If the aspnet roles data inside that json, it will appear as multiple row and datatable dont accept it.. If i remove that foreign key linkage, my datatable will display without any error.
In this case, what i want is, how to select aspnetusers table without pulling out its foreign table. For eg
db.AspNetUsers.Select(x=>x.AspNetUsers).ToList();
Turn off the LazyLoading. So that the children will not be fetched automatically.
try doing something like this (good for keeping the return object light and leave behind any unwanted columns):
(I have just made up some col name, but you get the idea.)
var result = (from a in db.AspNetUsers
select new AspNetUser { Name = a.Name,
othercol1 = a.othercol1,
othercol2 = a.othercol2,
}).ToList();
Footnote: In reality it is generally not good practice to return the actual db Entity to the front end so you might want to have your own Data Transfer Objects (DTO).
You configured that in the mappings using the Fluent API's methods
HasOptional
HasMany
Ignore
etc. But normally, I create schema-bound views in database and then map that in EF. It works really well in cases when we're only interested in a flattened query without all the joints.
Or use Linq to EF projections as JonhB's answer...
var result = (from a in db.AspNetUsers
select new AspNetUser { Name = a.Name,
...
}).ToList();
Just make sure you don't call ToList on db.AspNetUsers because that would materialize the query on AspNetUsers and all it's foreign key references and as result the projection is done in-memory after the query returns

Write in many to many relationship table with only primary key

I have two tables like this:
And between these tables there is a Junction table like this:
*appartiene_squadra*
field name (**primary key**)(*foreign key to first table*)
field name (**primary key**)(*foreign key to second table*)
Now, the problem is that the model recognize only the first two tables and I can't write data in appartiene_squadra. How I can write data here?
You're right in identifying that Entity Framework creates the junction table for you.
To enter data, you do not "add data to the junction table". What you do is add data to the navigational property, which will automatically be stored in the junction table by Entity Framework.
using(var db = new MyDataContext())
{
Installatori myInstallatori = db.GetExistingInstallatori(); //Assume this gives you an existing entity
Squadra mySquadra = db.GetExistingSquadra(); //Assume this gives you an existing entity
//You can do it this way
myInstallatori.squadra.Add(mySquadra);
//or this way
mySquadra.installatori.Add(myInstallatori);
//And then you save it to the database
db.SaveChanges();
}
I've shown an example of adding A to B, and B to A. Please note that you should only do one of these at the same time (at least when it is your intention to save to the database, rather than simply populating the entity in memory).
Also, to remove a row from the database:
mySquadra.installatori.Remove(myInstallatori);
db.SaveChanges();

How to change the column names of a mapping table?

I am creating an Entity Framework 6 database using the Empty EF Designer Model.
My issue can be duplicated as follows. I have two tables and a many to many association between them.
When I generate the database, it creates a third mapping table, which I expect. However, the names of the columns are unexpected.
CREATE TABLE [dbo].[WordWordType] (
[Words_WordId] int NOT NULL,
[WordTypes_WordTypeId] int NOT NULL
);
Notice that the mapping table has column names that are somewhat redundant and long. The column names include the table name, which is redundant, followed by an underscore, followed by the Key column name.
WordWordType
- Words_WordId
- WordTypes_WordTypeId
I am hoping EF 6 has a way to create the mapping table with column names that don't include the table name and underscore. I need the table to look as follows.
WordWordType
- WordId
- WordTypeId
At the moment you already have the table name in your primary key column name, which is - in my opinion - a redundant information.
If your name your primary key columns simply Id, then EF will automatically name your columns Word_Id and WordType_Id.
In Code First you can use fluent API
modelBuilder.Entity<Word>()
.HasMany(w => w.WordTypes)
.WithMany(wt => wt.Words)
.Map(x =>
{
x.ToTable("WordWordType");
x.MapLeftKey("WordId");
x.MapRightKey("WordTypeId");
});
but since you are using model first I think the only way is to change T4 file which is responsible for generating SQL script. You can find it in Database Script Generation section in your model properties.
Update
see this for debugging T4.
the SSDLToSQL10.tt contains two main section for this, one is Creating all tables on line 150 and another one is Creating all FOREIGN KEY constraints on line 196, they enumerate on Store.GetAllEntitySets() and Store.GetAllAssociationSets() and creating tables and foreign keys in database, debug the T4 file and see where your mapping table is created, I suspect it is in Store.GetAllEntitySets(), then change the generation the way you want.

Code First Entity Model.. Joined Table without Primary Key

im using Code First Entity Model with Web API Asp.Net
i need 3 tables in total
The First table(Table1) contains some information with a unique Id lets say it is like
string id
string model
The second Table (Table2)contains some information about the user. lets say it is
string Id
string name
string company
now i need a third table. which would only work as a joining table and would contain
Table1 ModelInfo
Table2 UserInfo
but it is showing me an error that table cannot be created with out a unique id. but as my architecture is i dont need a unique id
what should i do?
or do i need to change my architecture?
Your question is general EF CodeFirst Many-to-Many relationship.
Suggested readings:
EF CodeFirst - Build Many-to-Many relationships
Composite Key - question on StackOverflow
How to have Many to Many association in EF CodeFirst

Entity Framework One-To-Many Insert - Foreign Key violation

I'm using Entity Framework for the first time and I'm trying to create a object with a collection (and I want all the objects in the collection to be created in database as well) but I'm having some foreign keys violations.
My sample tables:
table APPOINTMENTS: ID, VAR1, DATE_APPOINTMENT
table GUESTS: ID, APPOINTMENT_ID, USER_ID, VAR2, VAR3
My test code:
DomainService aux = new DomainService();
APPOINTMENTS appointment = new APPOINTMENTS();
appointment.VAR1 = "BLA";
appointment.DATE_APPOINTMENT = new DateTime();
//The user with id = 1 is already created in the database
appointment.GUESTS.Add(new GUESTS { USER_ID = 1, VAR2 = 1, VAR3 = "F" });
aux.InsertAppointment(appointment);
At DomainService I have:
public void InsertAppointment(APPOINTMENTS appointment)
{
using (var context = this.ObjectContext)
{
context.AddToAPPOINTMENTS(appointment);
context.SaveChanges();
}
}
But I'm getting this error:
{"ORA-02291: integrity constraint (FK_GUESTS_APPOINTMENTS) violated - parent key not found"}
What am I doing wrong?
UPDATE:
To create the ID's in the database, I am using a sequence for each table and a trigger before insert to get the next value.
When I create a single object, e.g. a appointment without guests, it inserts in the database and it generates the id.
The solution to this problem:
"The ID fields that are generated from sequences won't be handled
correctly. After saving the entities the ID's will be returned as 0.
I'll fix this by manually hacking the SSDL (open your .edmx file in a
text editor) with StoreGeneratedPattern="Identity" attributes on the
ID fields (lines 6 and 16). Note that designer may rip that change out
upon future modification.
While I suppose it's not absolutely necessary it might also be prudent
to modify some type metadata such as changing "number"s to "int"s in
your SSDL and "Decimal"s to "Int32"s in your CSDL where applicable.
Frequently these don't auto-generate with the desired values
especially with XE."
#http://www.chrisumbel.com/article/oracle_entity_framework_ef
As for me, the problem was solved simply by opening diagram .edmx and changing property StoreGeneratedPattern from None to Identity for each Primary Key in each table. After saving everything was fine.
I'm using VS 2012, Entity Framework 5 (6 is not supported yet), Oracle 11.2, last ODP.NET 12, .Net 4.5
In case of EF code first approach, if this error come
(ORA-02291: integrity constraint (FK_GUESTS_APPOINTMENTS) violated -
parent key not found)
In my case there are 2 tables which have Identity columns. So I just added
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
property to my model class just above the the column which is identity column in database and it solved my problem :)
Hope this help :)
I cant see where you are setting your Primary Key (the ID property of the appointment class). Are you using a key generator on the database side? If not this should be the problem.
You're inserting a record with a foreign key value that is not found in the parent table that constraint refers back to.

Categories

Resources