Errors with non-mapped child entity - c#

I have a Parent and Child class/table and I'm using Fluent API to configure my mapping. The tables are joined on non primary key fields in each table, so according to what I've read, I can't configure the join in Entity Framework. Because of that, I'm going to load my Parent.Children property manually (parent.Children = (from x in context.Children...)
However, I'm getting an exception on my mapping of Parent. My classes look like
public class Parent
{
// Unique primary key
public int ParentPrimaryKey { get; set; }
// These two fields together compose the foreign key to join to Child
public string ParentForeignKey1 { get; set; }
public string ParentForeignKey2 { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
// Unique primary key
public int ChildPrimaryKey { get; set; }
// These two fields together compose the (non-unique) foreign key to join to Parent
public string ChildForeignKey1 { get; set; }
public string ChildForeignKey2 { get; set; }
}
When I try to query context.Parents, I get an exception because the SQL that Entity Framework generates is trying to join Parent to Child and is looking for a property on Child called Child_ParentPrimaryKey.
If I add modelBuilder.Entity<Parent>().Ignore(p => p.Children); I get the exception System.NotSupportedException: The specified type member 'Packages' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
How can I keep Children as a non-mapped property on Parent without getting errors?

You can exclude a property from EF mapping by adding the [NotMapped] attribute:
using System.ComponentModel.DataAnnotations.Schema;
public class Parent {
// ...
[NotMapped]
public List<Child> Children { get; set; }
}
DataAnnotations - NotMapped Attribute

Thanks to everyone who responded. Your comments made me realize the problem was that I was using the Parent.Children property in my LINQ query. I removed that, and it's working now.

Related

How automatically define navigational properties?

Let these 2 classes,
A Parent class
class Parent{
[Key]
public int Id { get; set; }
public virtual ICollection<Child> child { get; set; }
}
And a Child class
class Child {
[Key]
public int Id { get; set; }
[ForeignKey("Parent")]
public int Parent_Id { get; set; }
public Parent Parent{ get; set; }
}
I would like to set a new child class like this:
var child = new Child();
MyParentInstacnce.child.Add(child)
However, when I set the parent class state.
db.Entry(child).State = System.Data.Entity.EntityState.Added;
db.Entry(MyParentInstacnce).State = System.Data.Entity.EntityState.Modified;
I got the fallowing error:
Additional information: A referential integrity constraint violation occurred: The property value(s) of 'Parent_Id' on one end of a relationship do not match the property value(s) of 'Parent.Id' on the other end.
This problem is solved setting mannualy the value of child.Parent_Id to the current parent id.
I would like to know if is somehow possible to the EntityFramework set automatically the relational properties by doing MyParentInstacnce.child.Add(child)
How can I configure Entity Framework to automaticaly define navigational properties?
OBS
Entify Frameworks is able to make this happens., All you need to do is to DO NOT create the navigational properties. Then the navigational will be under the hood and the EF will make all the work. However in this case I really need to be able to read the navigational properties.

Saving related entities at once - An error occurred while saving entities that do not expose foreign key properties for their relationships

(I've checked the related questions, and can't find an answer.)
I'm doing some tests with Code First Entity Framework 6.
I have a "Child" entity that references two "Parent" entities.
I want to create the child entity and parent entities, and then save them all at once (so I can cut down on the number of db.Save() calls, and to keep it as one unit of work).
public class Child
{
public int ChildID { get; set; }
public string Name { get; set; }
public virtual Parent Father { get; set; }
public virtual Parent Mother { get; set; }
}
public class Parent
{
public int ParentID { get; set; }
public string Name { get; set; }
[ForeignKey("Child")]
public int? ChildID { get; set; }
public virtual Child Child { get; set; }
}
(A bit of a confusing setup -- the parents are actually the "children" of the child in the relationship. I know it's bad abstraction. This is just a test.)
Controller:
public ActionResult AddWithParents()
{
Parent father = new Parent { Name = "Test Father" };
Parent mother = new Parent { Name = "Test Mother" };
Child newChild = new Child
{
Name = "Test Child",
Father = father,
Mother = mother
};
db.Children.Add(newChild);
father.Child = newChild;
mother.Child = newChild;
db.SaveChanges();
return RedirectToAction("Index");
}
This works, but doesn't populate the Parent.ChildID foreign key.
If I do something like father.Child = newChild, I get the following error:
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.
Is there any way to get this to work?
I figured out problem source in your code: the ChildId property in Parent class declared as nullable integer type, while ChildId property in Child class belongs to non-nullable integer type, which they're different types (Nullable<int> against int).
Hence, you should declare ChildId property in Parent class as non-nullable type, thus circular reference problem should be solved as this:
public class Child
{
public int ChildID { get; set; }
public string Name { get; set; }
public virtual Parent Father { get; set; }
public virtual Parent Mother { get; set; }
}
public class Parent
{
public int ParentID { get; set; }
public string Name { get; set; }
[ForeignKey("Child")]
public int ChildID { get; set; } // set this FK as non-nullable int
public virtual Child Child { get; set; }
}
According to this answer, circular dependency problem occurs when a foreign key property data type mismatch with source primary key, or a foreign key property has been set incorrectly.
Edit: Since ChildId property in Child class is non-nullable int primary key property in database table, the best way to remove circular dependency is setting foreign key with same data type as primary key (i.e. int).
Related problem:
Clean way to deal with circular references in EF?
Unable to determine a valid ordering for dependent operations

EF LINQ - How to query 2 tables associated by foreign key?

Using EF 6 code first. I have an Entity class and a Name class, and want to query a list of all Entity objects with their respective Names so that I can show on a Gridview control.
These are my class definitions:
public class Entity
{
[Key]
public int EntityKey { get; set; }
public virtual ICollection<Name> Names { get; set; }
}
public class Name
{
[Key]
public int NameKey { get; set; }
public int EntityKey { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual Entity Entity { get; set; }
}
In my Data Access Layer, I have a method that gets all entities from database:
public List<Entity> GetEntities()
{
SdmDBContext entityDbContext = new SdmDBContext();
return entityDbContext.Entities.ToList();
}
but with this query, I don't get the Names that are associated to the Entity class. I have tried LINQ and lambda expressions, as well as an .Include operation, but not sure how to formulate the syntax properly.
How can I change the DAL method to return the Names associated with all existing entities?
You code is loading the list of Entities in the Entity table, and with 'lazy loading' it should also return associated Name collections when you access them. You declare your ICollection as virtual to enable 'lazy loading' because a proxy object will be created to make DB requests when you access something that hasn't been eagerly loaded.
Include is just a request to eagerly load related entities by using the navigation properties defined on the object. You can call Include using a lambda or string representing the name of the navigational property you want to eagerly load.
For example:
public List<Entity> GetEntities()
{
SdmDBContext entityDbContext = new SdmDBContext();
return entityDbContext.Entities.Include("Names").ToList();
}

EF Code First Navigation Property to same table

I'm new to EF and struggling to implement the following scenario. I have an entity I'd like to have a navigation property to another of the same entity. E.g.
public class Stage {
public int ID { get; set; }
public int? NextStageID { get; set; }
public string Name { get; set; }
public virtual Stage NextStage { get; set;}
}
The only example I've found so far was where the entity had a parent / child relationship, i.e. the navigation property was an ICollection of the same entity. I tried adapting this but couldn't get it to work in my instance. Also, I only need it to be one way, i.e. the entity doesn't have a 'PreviousStage' property, just a 'NextStage' one. I'm configuring using Fluent API. Could someone advise if / how this can be achieved?
I am getting this error:
Unable to determine the principal end of an association between the types 'namespace.Stage' and 'namespace.Stage'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations
Edit
Just realised in my slightly simplified example, I didn't show that NextStageID is optional (int?).
You can explicitly define the relation as follows:
public class Stage {
public int ID { get; set; }
public int NextStageID { get; set; }
public string Name { get; set; }
[ForeignKey("NextStageID ")]
public virtual Stage NextStage { get; set;}
}
you need to add a parentId and Parent navigation property
and Children navigation property so entity framework understands that is a recursive relation
check the answer in this stack Overflow link

EF One-to-many Foreign Keys without child navigation properties

Using code-first Entity Framework and .NET 4, I'm trying to create a one-to-many relationship between parents to children:
public class Parent
{
[Key]
public int ParentId { get; set; }
[Required]
public string ParentName { get; set; }
public IEnumerable<Child> Children { get; set; }
}
public class Child
{
[Key]
public int ChildId { get; set; }
[ForeignKey]
public int ParentId { get; set; }
[Required]
public string ChildName { get; set; }
}
As pointed out here, in order for foreign key relationship to carry into the database, the actual objects must be linked, not just their IDs. The normal way to do this if for a child to contain a reference to its parent (example).
But how do I enforce foreign keys in my implementation, which is the other way around (parent referencing children)?
First of all: You cannot use IEnumerable<T> for a collection navigation property. EF will just ignore this property. Use ICollection<T> instead.
When you have changed this, in your particular example you don't need to do anything because the foreign key property name follows the convention (name of primary key ParentId in principal entity Parent) so that EF will detect a required one-to-many relationship between Parent and Child automatically.
If you had another "unconventional" FK property name you still could define such a mapping with Fluent API, for example:
public class Child
{
[Key]
public int ChildId { get; set; }
public int SomeOtherId { get; set; }
[Required]
public string ChildName { get; set; }
}
Mapping:
modelBuilder.Entity<Parent>()
.HasMany(p => p.Children)
.WithRequired()
.HasForeignKey(c => c.SomeOtherId);
As far as I can tell it is not possible to define this relationship with data annotations. Usage of the [ForeignKey] attribute requires a navigation property in the dependent entity where the foreign key property is in.

Categories