I have a method for inserting in database.
I have 1:n relationship between the tables Point (n) and Line (1). Point has foreign key idLine.
However, the class Point in Entity Framework doesn't have the idLine property.
Now, in my method I have object of type Point, as parameter and here I have a problem because I don't know to what to assign the idSection of the new Point object which is inserted in the table.
How to add the idLine property in the Point class?
I'll assume you're using EF4.0, since this is not possible in previous version (EF1.0 does not include foreigh key properties in model).
In your generation wizard you need to make sure that "Include foreign key columns in the model" checkbox is checked when you're generating data model. Otherwise foreign key columns will be omitted when generating data.
If I'm remembering correctly you cannot simply add forign keys to classes that are already generated. You would need to manually edit all the mappings (not impossible, might be little bit troublesome if you are new to EF). Or you can simply remove this class from design area and add it again (making sure appropriate checkbox is checked this time). This might be simpler if you haven't customized generated classes.
add a foreign key in your model like following :-
public int? LineId { get; set; }
public virtual LineId LineId {get; set; } // this for one to one
Related
I'm trying to create a One-to-One relationship between two tables using a primary key and a unique key of the two tables (rather the primary keys).
The following is what I'd like to work.
// The principal end
public class A
{
// The primary Key
public int AId { get; set; }
// The navigation property
public virtual B B { get; set; }
}
// The dependent end
public class B
{
// The primary Key
public int BId { get; set; }
// The unique key
[Index(IsUnique = true)]
public int AId { get; set; }
// The navigation property
public virtual A A { get; set; }
}
But then I see this error:
Unable to determine the principal end of an association between the types 'A' and 'B'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
I'm quite sure a primarykey-uniquekey relationship is allowed in SQL Server. Looks like EF6 doesn't support it. EF Core 1.0 seems to, but it's not feasible to port to EF Core right now.
Why we need a need a relationship of this kind:
We have two tables A and B in production, but the one-to-one relationship, which should have been there is missing. The relationship is something we need so we can navigate from an A object to a B object with EF. Since both tables have values, we can't really make the primary key, the foreign key - we'll end up with incorrect data.
My approach to fixing this was to:
add a column
fill it with the correct A ids
make it unique
establish the 1-1 relationship
An alternate approach to fixing this is more than welcome.
This is possible with EF Core using Fluent API's .HasPrincipalKey() method. Unfortunately not supported in EF6 which is a shame as relationships over unique keys can essentially be treated the same as foreign key constrains so I'd imagine it would have been an easy addition.
Now that MS has forgot about EF6 and is focusing on EF Core, this will never happen. I really liked using the visual entity designers as it saved so much time. Looking at the thousand+ lines of code the EF Core DbContext scaffold generator spits out for me is discouraging to say the least. Sure, it's pretty when you're dealing with a demo project consisting of two cute tables but we all know this is never the case in the real world. The whole point of using an ORM is to save time but I'm not sure if having to manage thousands of lines of configuration code is any better. Just by two cents.
I have two entities
public class Account
{
[Key]
public int Id { get; set;
public int MemberInfoId { get; set; }
public Member MemberInfo { get; set; }
//Other Properties
}
public class Member
{
[Key]
public int Id { get; set; }
//Other Properties
}
With following relationship
modelBuilder.Entity<Account>()
.HasRequired(a => a.MemberInfo)
.WithMany()
.HasForeignKey(a => a.MemberInfoId)
.WillCascadeOnDelete(true);
However, an Account has one Member only so the following relation is better suited (I guess)
modelBuilder.Entity<Account>()
.HasRequired(a => a.MemberInfo)
.WithRequiredPrincipal()
.WillCascadeOnDelete(true);
But code first migration won’t migrate to that. It gives the following error
The object 'PK_dbo.Members' is dependent on column 'Id'.
The object 'FK_dbo.Accounts_dbo.Members_MemberInfo_Id' is dependent on column 'Id'.
ALTER TABLE DROP COLUMN Id failed because one or more objects access this column.
What can I do to alter the relation without recreating the database to keep the already inserted data?
First, you can read this page on mixing code-based migrations with automatic migrations to see if you even want to go this route in the first place. Generally, it's not a good idea if you have a team involved.
Next, it might be good to know that if you change the relationship between Member and Account to a one-to-one, Entity Framework requires that the primary key on the dependent side also be the foreign key. The column that used to be the primary key on the dependent side will become useless from EF's perspective. You also won't need the Account.MemberInfoId anymore, either.
Finally to create a migration, after you finish modifying the models, you can run Add-Migration with a migration name. This will create a migration file with a DbMigration class that you can modify. You'll probably need to do something like the following:
Create a new column in Member that will hold the new foreign key
Use Sql() to update values in that column with the primary key of the associated account
Drop the foreign key constraint, index, and primary key
Drop the account.memberinfo_id column and member.id column (which is optional, but if you don't drop the member.id column, you'll have to make sure to map the model's Member.Id property to the column created above).
Rename new column in member to id
Add primary key to new column in Member
Add index and foreign key
I'm sure I've missed something, but that's the general gist. I'd probably also backup everything, since something's guaranteed to go wrong the first five times or so.
I am attempting to use Entity Framework with a database that does not make use of foreign keys. To make matters worse, tables that have a relationship make use of relating fields that can be null. For example the Order table has a column for ClientID that is nullable. Keeping in mind I did not create this database nor can I change it I would like to still be able to use Entity Framework (v6.1) to perform CRUD operations on the database.
The problem, as you might expect, has to do with the association between entities. I can create the associations myself manually but I cannot set the referential integrity because the properties in the entities map to columns in the database that can be NULL.
Is there a way to get around this? Perhaps a way to use the associations without having to define referential integrity? Granting that it would be up to me to make sure that any child records be deleted if a given parent is deleted..
I think this will work:
public class Order
{
//other properties
public int? ClientId {get; set;}
}
And set
modelBuilder.Entity<Order>()
.HasOptional(x=>x.Client)
.WithMany(x=>x.Orders)
.WithForeignKey(x=>x.CliendId);
When setting up a new Entity data Model, there is an option to
[x] Pluralize or singularize generated object names
I have noticed this is an option in LINQ as well. Also, now that I am studying the ADO.NET entity framework, I noticed it also has 'DEFAULT' to 'pluralize or singularize generated object names'
What is the result of not checking/allowing this option when setting up the 'Entity Data Model'.
What Advantages/Disadvantages/issues will I face by making a selection one way or the other?
If you check Pluralize or singularize generated object names, the set in the class context.cs genrated by EF will be named in the format:
public virtual DbSet<SomeTableName> SomeTableNames { get; set; }
if not check, it'll be named:
public virtual DbSet<SomeTableName> SomeTableName { get; set; }
Advantages/Disadvantages IMHO:
I would like to see collection set be named ending with 's', such as dbset colleciton of Employee class of Employee Table named Employees, so I'll check the option. But I guess maybe someone would like to treat the dbset as a table, so he/she would like to name it same as table name Employee.
No problem at all, except that you'll probably want to do it manually. Usually, you want entity names singular and entity set names plural.
How do I have to set up a property so that when using SaveChanges, the many to one relationship is saved and I don't get the: INSERT statement conflicted with the FOREIGN KEY constraint... error.
Pretty simple, I have an Ad and an AdType where there are many Ads to one AdType. There is a property on Ad:
public class Ad
{
public Int32 AdTypeId { get; set; }
public virtual AdType AdType { get; set; }
}
To cover this relationship.
When I do this:
someAd.AdType = someAdType;
The property is set just fine, but the AdTypeId is not. No worries though since I would assume this would be ok to save.
context.SaveChanges();
Problem is at this point it is trying to save the 0 value in the AdTypeId column (Causing a foreign key issue) instead of using the object assigned AdType property to figure out what it should insert into the AdTypeId column.
Things I know:
At this point someAdType is
persisted/has an id.
The AdType property is set correctly.
The AdTypeId is 0.
There is a foreign key relationshipin the database.
AdTypeId is a primary key.
I have deferred/lazy loading set to true
I haven't really tried changing the AdType since it is set up to allow lazy loading.
Ok looks like because I am using the non proxied (Made that word up... Yah) "Snapshot based Change Tracking" approach, the system has no real idea that it's changed.
In this example, Customer is a pure
POCO type. Unlike with EntityObject or
IPOCO based entities, making changes
to the entity doesn’t automatically
keep the state manager in sync because
there is no automatic notification
between your pure POCO entities and
the Entity Framework. Therefore, upon
querying the state manager, it thinks
that the customer object state is
Unchanged even though we have
explicitly made a change to one of the
properties on the entity.
Got that from here
So in order to make sure it knows to check to see if there has been a change I have to use the AcceptAllChangesAfterSave option with the SaveChanges method.
context.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);
And it works. Hopefully I understand it correctly...