Fluent API map composite pattern object - entity-framework

I am trying to map a composite object using FluentAPI on entity framework 5.0 for the following model:
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<Category> Children { get; set; }
}
So far tried many ways that didn't work well, such as the following:
HasKey(t => t.CateroryId);
HasOptional(c => c.Children)
.WithMany()
.HasForeignKey(c => c.CateroryId);
Any idea how I might do that?

If I've understood what you're going for - a Category is able to have many categories as children.
I've done this in the past using a similar foreign key mapping and some additional properties, although there may be a way to do it using independent association.
Adding additional properties to your Category so we can keep track of the parent/child relationship:
public class Page
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public int? ParentID { get; set; } // Nullable (Parent is optional).
// Navigation properties
public virtual Category Parent { get; set; } // Optional Parent
public virtual ICollection<Category> Children { get; set; }
}
You should then be able to configure like so (depending on where your mappings are set):
this.HasMany(c => c.Children) // Many Children
.WithOptional(c => c.Parent) // Optional Parent
.HasForeignKey(x => x.ParentID);

Related

Breeze doesn't fill one-to-many navigation property with optional inverse property

I have the following classes:
public class SalesProduct
{
public int Id { get; set; }
public ICollection<Image> ProductImages { get; set; }
}
public class Image
{
public int Id { get; set; }
public int? SalesProductId { get; set; }
public virtual SalesProduct SalesProduct { get; set; }
}
and the Fluent API configuration for SalesProduct:
HasMany(x => x.ProductImages)
.WithOptional(x => x.SalesProduct)
.HasForeignKey(x => x.SalesProductId);
SalesProduct has the ProductImages collection and EF sends it to the frontend, but Breeze doesn't fill it (it has length 0). Should it work? Am I missing something?
Edit: The relation is loaded using eager loading in backend.
ProductImages needs to be marked as virtual as well for EF to lazily load related entities
public virtual ICollection<Image> ProductImages { get; set; }
It should work! It started to work after a while without taking any actions.

How to store childrens of the same model with entity framework?

I have model Page:
public int Id{ get; set; }
public string Name { get; set; }
I want to have children pages there:
public int Id{ get; set; }
public string Name { get; set; }
public List<Page> Childrens { get; set; }
What the best way to setup non required children items of same model?
The way I went about it requires a few additional properties in your model (I'm using the virtual` keyword for my navigation properties because I required lazy loading):
public class Page
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentID { get; set; } // Nullable int because your Parent is optional.
// Navigation properties
public virtual Page Parent { get; set; } // Optional Parent
public virtual List<Page> Children { get; set; }
}
Then, using a foreign key association, you can configure the relationship like so (this is my Page mapping):
// You may be configuring elsewhere, so might want to use `modelBuilder.Entity<Page>()` instead of `this`
this.HasMany(t => t.Children)
.WithOptional(t => t.Parent)
.HasForeignKey(x => x.ParentID);
Essentially, every child is aware of its parent, and as a result of the navigation properties, you can explore the relationship from both sides.

Entity framework Multiple Parent for a child

How can I implement a child that has multiple parents in Entity Framework?
The resulting tables must be as follows:
1.Courses:
CourseID int identity
CourseTitle nvarchar
.
.
.
OtherColumns as neede
2.CoursePreRequisites:
CourseID (FK to Course.CourseID)
PreRequisiteCourseID (FK to Course.CourseID)
or is there any better way to achieve multiple parent for a child record?
You just need two navigation properties in the child class refering to the same parent class and - optionally - two corresponding foreign key properties:
public class Course
{
public int CourseID { get; set; } // PK property
public string CourseTitle { get; set; }
}
public class CoursePreRequisite
{
public int CoursePreRequisiteID { get; set; } // PK property
public int CourseID { get; set; } // FK property 1
public Course Course { get; set; } // Navigation property 1
public int PreRequisiteCourseID { get; set; } // FK property 2
public Course PreRequisiteCourse { get; set; } // Navigation property 2
}
If one or both of the two relationships are optional, use int? instead of int for the foreign key properties.
If you use the property names as indicated in the example above you don't need to configure anything. EF will recognize the two one-to-many relationships by naming conventions.
You can also use collections as inverse properties in the Course entity if you need or want them:
public class Course
{
public int CourseID { get; set; } // PK property
public string CourseTitle { get; set; }
public ICollection<CoursePreRequisite> PreRequisites1 { get; set; }
public ICollection<CoursePreRequisite> PreRequisites2 { get; set; }
}
However, in that case you must specify which navigation property pairs belong together in a relationship. You can do this with data annotations for example:
[InverseProperty("Course")]
public ICollection<CoursePreRequisite> PreRequisites1 { get; set; }
[InverseProperty("PreRequisiteCourse")]
public ICollection<CoursePreRequisite> PreRequisites2 { get; set; }
Or with Fluent API:
modelBuilder.Entity<Course>()
.HasMany(c => c.PreRequisites1)
.WithRequired(p => p.Course) // Or WithOptional
.HasForeignKey(p => p.CourseID);
modelBuilder.Entity<Course>()
.HasMany(c => c.PreRequisites2)
.WithRequired(p => p.PreRequisiteCourse) // Or WithOptional
.HasForeignKey(p => p.PreRequisiteCourseID);

EF many-to-many with two properties

I have a sample code:
public class Tag
{
public int TagId { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User
{
public int UserId { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
When I run EF over my model (i use code first approach), i get some tables automatically created in my db:
Users
Tags
UserTagUsers <-- junction table for many-to-many relationship
It is okay, till I decide to add one more property to User entity:
public class User
{
public int UserId { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public virtual ICollection<Tag> Tags2 { get; set; }
}
in this case EF generates completely different relations, it removes UserTagUsers junction table, but adds some additional properties to Tags table in order to make it one-to-one mapping.
How can I explicitly tell EF to make the property Tags and Tags2 to be many-to-many?
Use fluent API to configure the mappings
modelBuilder.Entity<User>()
.HasMany(u => u.Tags).WithMany(t => t.Users)
.Map(m =>
{
m.ToTable("UserTags");
m.MapLeftKey("UserId");
m.MapRightKey("TagId");
});
modelBuilder.Entity<User>()
.HasMany(u => u.Tags2).WithMany(t => t.Users2)
.Map(m =>
{
m.ToTable("UserTags2");
m.MapLeftKey("UserId");
m.MapRightKey("TagId");
});

Is there a data annotation equivalent to Entity Framework's fluent API's WillCascadeOnDelete()? [duplicate]

I'm currently using EF Code First 4.3 with migrations enabled, but automatic migrations disabled.
My question is simple, is there a data annotations equivalent of the model configuration .WillCascadeOnDelete(false)
I would like to decorate my class so that the foreign key relationships do NOT trigger a cascading delete.
Code sample:
public class Container
{
public int ContainerID { get; set; }
public string Name { get; set; }
public virtual ICollection<Output> Outputs { get; set; }
}
public class Output
{
public int ContainerID { get; set; }
public virtual Container Container { get; set; }
public int OutputTypeID { get; set; }
public virtual OutputType OutputType { get; set; }
public int Quantity { get; set; }
}
public class OutputType
{
public int OutputTypeID { get; set; }
public string Name { get; set; }
}
I Would like to do something like this:
public class Output
{
[CascadeOnDelete(false)]
public int ContainerID { get; set; }
public virtual Container Container { get; set; }
[CascadeOnDelete(false)]
public int OutputTypeID { get; set; }
public virtual OutputType OutputType { get; set; }
public int Quantity { get; set; }
}
This way i would be able to scaffold the migration correctly. which scaffolds the foreign key relationships to be cascade deleted at the moment.
Any ideas, other than using Model Configuration?
No there is no such equivalent. You must use fluent API to remove cascade delete selectively or you must remove OneToManyCascadeDelete convention to remove it globally.
Create a mapping class (the fluent syntax) and use the code below:
// add relationships "Post" and "User" to a "Comment" entity
this.HasRequired(t => t.Post)
.WithMany(t => t.Comments)
.HasForeignKey(d => d.PostID)
.WillCascadeOnDelete(false); // <---
this.HasOptional(t => t.User)
.WithMany(t => t.Comments)
.HasForeignKey(d => d.UserID)
.WillCascadeOnDelete(false); // <---
Here's a nice post on how to set up fluent mappings if you need more info.
Just make the FK property nullable can prevent cascade delete from happening:
public int? OutputTypeID { get; set; }