How to eager fetch multi level objects with NHibernate - c#

I have the following Entity's:
public class Parent
{
public string Id { get; set; }
public Ilist<Child> Children { get; set; }
}
public class Child
{
public string Id { get; set; }
public Ilist<Parent> Parents { get; set; }
public Ilist<Grandchild> GrandChildren { get; set; }
}
public class Grandchild
{
public string Id { get; set; }
public Child parent { get; set; }
}
And their mappings:
public class ParentMap
{
HasManyToMany(x => x.Children).Table("P_C").LazyLoad();
}
public class ChildMap
{
HasManyToMany(x => x.Parent).Table("P_C").Inverse();
HasMany(x => x.Parents).KeyColumn("ParentID").Cascade.All().Inverse();
}
public class GrandchildMap
{
References(x => x.parent).Column("ParentID").Not.Nullable();
}
I want to fetch Eager all the levels using NHibernate 4
When i try Getting a single Parent by ID like:
var Parent = session.QueryOver<Parent>().Where(x => x.Id == Id).
Fetch(x => x.Children).Eager.
Fetch(x => x.Children.First().GrandChildren).Eager.
TransformUsing(Transformers.DistinctRootEntity).
List<Parent>().FirstOrDefault();
I get "cannot simultaneously fetch multiple bags" Exception

Related

How to include 2 parents to a child list in Entity Framework Core? [duplicate]

This question already has an answer here:
EFCore Linq ThenInclude Two Foreign Keys To Same Table
(1 answer)
Closed 3 months ago.
I have this class and a context class:
public class Parent
{
public int Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public int ForeignId { get; set; }
[ForeignKey("ParentId")]
public virtual Parent Parent{ get; set; }
[ForeignKey("ForeignId")]
public virtual Foreign Foreign{ get; set; }
public virtual ICollection<GrandChild> GrandChildren { get; set; }
}
public class GrandChild
{
public int Id { get; set; }
public int ChildId { get; set; }
[ForeignKey("ChildId")]
public virtual Child Child{ get; set; }
}
public class Foreign
{
public int Id { get; set; }
public string name { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
I want to show a list of Parent with Including their children and granchildren. I want to include Foreign table, too. because I need its fields.
I wrote this code:
var list = context.Parents.Include(p => p.Children).ThenInclude(p => p.GrandChildren).Tolist();
How Can I add or include foreign table to this query?
I wrote below code but it had error:
var list = context.Parents
.Include(p => p.Children)
.ThenInclude(p => p.GrandChildren)
.Include(p => p.Children.FirstOrDefault().Foreign).Tolist();
You need to add 2 includes:
var list = context.Parents
.Include(p => p.Children)
.ThenInclude(c => c.GrandChildren)
.Include(p => p.Children)
.ThenInclude(c => c.Foreign).ToList();

Entity Framework Load Child With Parent

public class Parent {
public int Id { get; set; }
public string Name { get; set; }
public Child ChildField { get; set; }
}
public class Child {
public int Id { get; set; }
public int Age { get; set; }
public int ParentId { get; set; }
}
public class MyDbContext : DbContext {
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Childs { get; set; }
}
DB Rows:
parent_id | name
1 "Parent 1"
2 "Parent 2"
Child Rows
child_id | age | parent_id
3 15 1
4 21 2
I have a method that looks like this:
public Parent Get(int parentId) {
var result = this.dbContext.Parents
.Join(
this.dbContext.Childs,
p => p.Id,
c => c.ParentId,
(p, c) => new { Parent = p, Child = c })
.AsNoTracking().Where(m => m.Parent.Id == parentId)
.FirstOrDefault()
result.Parent.Child = result.Child;
return result.Parent;
}
This is currently working for me, but I'd like to not have to manually assign the child to the parent after this join.
Is there a better way to do this? I would like to use this same style of syntax.
How can I accomplish this without having to manually assign the Child to the Parent?
Thanks!
The including...
FatherRepository.All().Including(x => x.Childs, x => x.Childs.Select(y => y.ChildChild));
Father class...
public class Father
{
public int Id { get; set; }
#region Navigations Properties
public virtual List<Child> Childs { get; set; }
#endregion
}
Child class...
public class Child
{
public int Id { get; set; }
public int ChildChildId { get; set; }
public int FatherId { get; set; }
#region Navigations Properties
public virtual Father Father { get; set; }
public virtual ChildChild ChildChild { get; set; }
#endregion
}
ChildChild class...
public class ChildChild
{
public int Id { get; set; }
}
Just write :
var result = this.dbContext.Parents.Where(m => m.Parent.Id == parentId)
.Include(p=>p.Child).FirstOrDefault()
result will contains corresponding childs

Entity Framework - The foreign key component … is not a declared property on type

I have the following Model
public class FilanthropyEvent : EntityBase, IDeleteable
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime EventDate { get; set; }
public string Description { get; set; }
public decimal Target { get; set; }
public decimal EntryFee { get; set; }
public bool Deleted { get; set; }
public ICollection<EventAttendee> EventAttendees { get; set; }
}
public class Attendee : EntityBase, IDeleteable
{
public int Id { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool MailingList { get; set; }
public bool Deleted { get; set; }
public ICollection<EventAttendee> EventAttendees { get; set; }
}
Events and Attendees is a many to many relationship but I needed another property on the association so I created an association entity
public class EventAttendee : EntityBase
{
public int FilanthropyEventId { get; set; }
public int AttendeeId { get; set; }
public bool InActive { get; set; }
public virtual Attendee Attendee { get; set; }
public virtual FilanthropyEvent FilanthropyEvent { get; set; }
}
These are the configurations for each FilanthropyEvent and Attendee
public class FilanthropyEventConfiguration : EntityTypeConfiguration<FilanthropyEvent>
{
public FilanthropyEventConfiguration()
{
HasKey(x => x.Id);
Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(x => x.EventAttendees).WithRequired(x => x.FilanthropyEvent).HasForeignKey(x => x.FilanthropyEvent);
}
}
public AttendeeConfiguration()
{
HasKey(x => x.Id);
Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(x => x.EventAttendees).WithRequired(x => x.Attendee).HasForeignKey(x => x.AttendeeId);
}
public class EventAttendeesConfiguration : EntityTypeConfiguration<EventAttendee>
{
public EventAttendeesConfiguration()
{
HasKey(x => new {x.FilanthropyEventId, x.AttendeeId});
}
}
When I try and initialise the database via the update-database command in the package manager console I get the following error.
System.InvalidOperationException: The foreign key component 'FilanthropyEvent' is not a declared property on type 'EventAttendee'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.
I realise I'm probably missing a mapping in the EventAttendeesConfiguration class but what would be the correct mapping to model this relationship?
This code
HasMany(x => x.EventAttendees)
.WithRequired(x => x.FilanthropyEvent)
.HasForeignKey(x => x.FilanthropyEvent);
Should be
HasMany(x => x.EventAttendees)
.WithRequired(x => x.FilanthropyEvent)
.HasForeignKey(x => x.FilanthropyEventId);

Automapper complex object mapping NullReference exception

I have the following classes
public class Group
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<GroupTier> Tiers { get; set; }
}
public class GroupTier : IEntity
{
public int Id { get; set; }
public int GroupId { get; set; }
public int Tier { get; set; }
public decimal Amount { get; set; }
public virtual Group Group { get; set; }
}
I am trying to map to the following ViewModel
public class GroupViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<decimal> Tiers { get; set; }
}
using the configuration
configuration.CreateMap<Group, GroupViewModel>()
.ForMember(m => m.Tiers, opt => opt.MapFrom(u => u.Tiers.OrderBy(q => q.Tier).Select(q => q.Amount)));
I am using EF6 to query from the database. I am having trouble when the Group.Tiers is null. How can I handle the null value?
When I use the this configuration
configuration.CreateMap<Group, GroupViewModel>()
.ForMember(m => m.Tiers, opt => opt.MapFrom(u => u.Tiers == null ? new List<decimal>() : u.Tiers.OrderBy(q => q.Tier).Select(q => q.Amount)));
I am getting this error
Cannot compare elements of type 'System.Collections.Generic.ICollection'

Best method to search on table with self join

I have classes like these in c#:
public class Family
{
public virtual string Description { get; set; }
public virtual Family Parent { get; set; }
public virtual IList<Family> Childrens { get; set; }
public virtual IList<Produt> Produts { get; set; }
}
public class Produt
{
public virtual string Description { get; set; }
public virtual Family Family { get; set; }
}
After this, I did the mappings:
public partial class FamilyMap : AbstractEntityMap<Family>
{
public FamilyMap()
{
Map(x => x.Description).Length(100);
References(x => x.Parent, "IdParent");
HasMany(x => x.Childrens).KeyColumns.Add("IdParent");
HasMany(x=>x.Produts);
}
}
public partial class ProdutMap : AbstractEntityMap<Produt>
{
public ProdutMap()
{
Map(x => x.Description).Length(100);
References(x => x.Family);
}
}
Imagine a Family with a lot of childrens and each children with a lot of childrens... What the best method to know the produts that belong to parent with id=3, for example...
P.S. Id is in the AbstractEntityMap.
use recursive With statement at SQL side

Categories