none
Issue loading child entities of a parent entity. Unidirectional mapping and has one to Zero or One relationship with a Shared primary key? RRS feed

  • Question

  • I have a Parent entity 'Association' which has a child entity 'Customer' the relationship is one to zero or one they both share common primary key. And mapping between them is uni directional.I'm using EF6 and Fluent API

        public class Association
        {
           public virtual long Id { get; set; }
           public virtual string ExternalId { get; set; }
           public virtual int OrganizationId { get; set; }
           public virtual AssociationType AssociationType { get; set; }
           public virtual Customer Customer {get; set;}
           public Association()
           {
               Customer = new Customer();
           }
        }
    Customer class.
    
        public class Customer
        {
          public virtual long Id { get; set; } //Shared primary key
          public virtual ICollection<Item> Items {get; set;}
          public virtual ICollection<Complaint> Complaints {get; set;}
          public customer()
          {
            Items = new List<Item>();
            Complaints = new List<Complaint>();
          }
        }
    
    Mapping are Uni directional:
    
        public class AssociationMapping:EntityTypeConfiguration<Association>
        {
           public AssociationMapping() : base()
           {
             HasKey(x => x.Id);
             Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
             Property(x => x.ExternalId).IsRequired();
             Property(x => x.OrganizaionId).IsRequired();
             Property(x => x.AssociationType);
             HasOptional(x => x.Customer).WithRequired().WillCascadeOnDelete();
           }
        }
    
        public class CustomerMapping : EntityTypeConfiguration<Customer>
        {
          public CustomerMapping ():base()
          {
            HasKey(x => x.Id);
            Property(x => x.Id);
            HasMany(x => x.Items)
    	       .WithOptional()
    	       .HasForeignKey(key => key.CustomerId)
    	       .WillCascadeOnDelete();
            HasMany(x => x.Complaints)
    	      .WithOptional()
    	      .HasForeignKey(key => key.CustomerId)
    	      .WillCascadeOnDelete();
          } 
        }

    When I Load Association entity it loads perfectly but child entity Customer is loaded with default values when i try to load Customer explicitly it throws the exception. Multiplicity constraint violated. The role 'Association_Customer_Target' of the relationship 'CodeFirstNamespace.Association_Customer' has multiplicity 1 or 0..1.

    var dbassociation = Single<Association>(x => x.OrganizationId== asso.organizationId && x.ExternalId == asso.ExternalId && x.AssociationType == asso.AssociationType);
    
    dbassociation.Customer = Single<Customer>(x => x.id == dbassociation.id);
    
    
     public TEntity Single<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>>criteria) 
    {
      return Context.Set<TEntity>().SingleOrDefault(criteria);   
    }


    For testing purpose I have tried to eager load by removing virtual on Customer property in association class and tried following but it throws same excepetion

    Context.Configuration.LazyLoadingEnabled = false;
    Context.Entry<Association>(dbassociation).Reference<Customer>(pa => pa.Customer).Load();

    I have also tried which throws same exception

    var dbassociation = Context.Set<Association>().Include("Customer").SingleOrDefault(x => x.OrganizationId== asso.organizationId && x.ExternalId == asso.ExternalId && x.AssociationType == asso.AssociationType);
      

    I want Association entity to be loaded and when we call Association.Customer it should load Customer. Please let me know your comments and suggestions.





    • Edited by Mady007 Tuesday, November 26, 2013 3:30 PM
    Tuesday, November 26, 2013 3:22 PM

Answers

  • Firstly I must appreciate your time and Thank you very much for your answer. I have raised the same question in  http://stackoverflow.com/a/20225347/2335546 it was answered there. The key difference was of instantiating the customer object in default constructor of Association. If you notice Association class in your answer it is not instantiating the customer object that's the reason its working for you and it wasn't for me. If I comment it then it is working. I thank you once again. 
    • Marked as answer by Mady007 Wednesday, November 27, 2013 4:18 PM
    Wednesday, November 27, 2013 2:35 PM

All replies

  • Hello Mady007,

    >>I want Association entity to be loaded and when we call Association.Customer it should load Customer.

    With the codes provided by you, I made a test, however, it worked fine that achieved it.

    My entities class:

    class Association
    
        {
    
            public int Id { get; set; }
    
            public string AssociationName { get; set; }
    
            public virtual Customer Customer { get; set; }
    
        }
    
    class Customer
    
        {
    
            public int Id { get; set; }
    
            public string CustomerName { get; set; }
    
        }
    

    Since I do not know the structure of Item and Complaint entities, I removed them.

    My context class, it will create a 1-1..0 relationship:

    class OneToOneZeroContext : DbContext
    
        {
    
            public DbSet<Association> Associations { get; set; }
    
            public DbSet<Customer> Customers { get; set; }
    
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
            {
    
                modelBuilder.Entity<Association>().Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    
                modelBuilder.Entity<Association>().HasOptional(a => a.Customer).WithRequired().WillCascadeOnDelete();
    
    
                modelBuilder.Entity<Customer>().Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    
    
            }
    
        }
    

    Query codes:

    internal void Execute()
    
            {
    
                using (OneToOneZeroContext db = new OneToOneZeroContext())
    
                {
    
                    //db.Database.Create();
    
                    var dbassociation = db.Associations.SingleOrDefault(a => a.Id == 1);
    
    
                    dbassociation.Customer = db.Customers.SingleOrDefault(x => x.Id == dbassociation.Id);
    
    
                }
    
            }
    

    The result:

    There is no error. You can have a try.

    For error message “entity framework multiplicity constraint violated. the role of the relationship has multiplicity 1 or 0..1”, there are some threads regarding it:

    http://stackoverflow.com/questions/16716754/multiplicity-constraint-violated

    http://stackoverflow.com/questions/15423713/multiplicity-constraint-violated-the-role-xxx-of-the-relationship-xxx-has-multi

    http://entityframework.codeplex.com/workitem/1257

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, November 27, 2013 6:25 AM
    Moderator
  • Firstly I must appreciate your time and Thank you very much for your answer. I have raised the same question in  http://stackoverflow.com/a/20225347/2335546 it was answered there. The key difference was of instantiating the customer object in default constructor of Association. If you notice Association class in your answer it is not instantiating the customer object that's the reason its working for you and it wasn't for me. If I comment it then it is working. I thank you once again. 
    • Marked as answer by Mady007 Wednesday, November 27, 2013 4:18 PM
    Wednesday, November 27, 2013 2:35 PM