none
Specifying many:one relation on a complex type - How! RRS feed

  • Question

  • Taking a small portion of the DDD sample, consider I have the following classes:

     

      public class Cargo {
        public int Id { get; set; }
        public Delivery Delivery { get; set; }
      }
    
      public class Delivery {
        public Location LastKnownLocation { get; set; }
        public Delivery() { }
      }
    
      public class Location {
        public int Id { get; set; }
        public string Name { get; set; }
      }
    

    When configuring the Cargo class, I am writing the following:

     

     

      public class CargoEntityTypeConfiguration : EntityTypeConfiguration<Cargo> {
        public CargoEntityTypeConfiguration() {
          this.HasKey(e => e.Id);
          this
            .HasRequired(e => e.Delivery.LastKnownLocation)
            .WithMany()
            .Map(m => m.MapKey("last_loc_id"))
            .WillCascadeOnDelete(false);
        }
      }
    
    

    The Location class has its own simple entity type configuration as well. In theory, this is supposed to prdocue the following database scheme:

     

    Table Cargo
    [pk] id
    [fk] last_loc_id
    
    Table Location
    [pk] id
    Name


    With last_loc_id being my foriegn key. Exactly as I want it! However, EF throws InvalidOperationException with the message: The expression 'e => e.Delivery.LastKnownLocation' is not a valid property expression. The expression should represent a property: C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'.

    So my question is how do I go about building the scheme based on the above class composition? Any help appreciated!


    • Edited by alaatm Wednesday, November 30, 2011 4:59 AM typo
    Wednesday, November 30, 2011 4:57 AM

Answers

  • Hi alaatm,

    If you want to put the navigation in Complex type, I don't think this is supported in Code First and EF. As @Rune's reply, you can create 1:1:1 relation among the three entities, but it doesn't fill your original requirement, thanks for understanding.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Edited by Alan_chenModerator Thursday, December 1, 2011 8:58 AM
    • Marked as answer by alaatm Thursday, December 1, 2011 4:38 PM
    Thursday, December 1, 2011 8:58 AM
    Moderator

All replies

  • Hi,

    The fluent api HasRequired must have a property on the base level, not in an navigation property. So you need first to connect Cargo with Delivery, and then Delivery with location.

    I have never used EntityTypeConfiguration to do this, but if you take this from a another approach, maybe it works?

      //The cargo class
      public class CargoEntityTypeConfiguration : EntityTypeConfiguration<Cargo> {
        public CargoEntityTypeConfiguration() {
          this.HasKey(e => e.Id);
          this.HasRequired(e => e.Delivery)
               .WithMany()
               .Map(m => m.MapKey("delivery_id"))
               .WillCascadeOnDelete(false);
        }
      }
    
    
      //A seperate configuration class for Delivery
      public class DeliveryEntityTypeConfiguration : EntityTypeConfiguration<Delivery> {
        public DeliveryEntityTypeConfiguration() {
          this.HasRequired(e => e.LastKnownLocation)
              .WithMany()
              .Map(m => m.MapKey("last_loc_id"))
              .WillCascadeOnDelete(false);
        }
      }
    

     


    --Rune

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful" if the post helped you to a solution of your problem.
    Thursday, December 1, 2011 7:06 AM
  • Unfortunately this wont work in my case as this make a table "entity" for Delivery where it is not an entity. It is just a property to the Cargo class with additional properties that will be mapped to the Cargo table.
    Thursday, December 1, 2011 7:54 AM
  • Hi alaatm,

    If you want to put the navigation in Complex type, I don't think this is supported in Code First and EF. As @Rune's reply, you can create 1:1:1 relation among the three entities, but it doesn't fill your original requirement, thanks for understanding.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Edited by Alan_chenModerator Thursday, December 1, 2011 8:58 AM
    • Marked as answer by alaatm Thursday, December 1, 2011 4:38 PM
    Thursday, December 1, 2011 8:58 AM
    Moderator
  • hello,

    I wrote this some times ago.

    There is a little difference from your code :

     HasRequired(p => p.GThirdParty).WithMany(t => t.GBusinesses).Map(x => x.MapKey("AFF_TIERS"));
    


    See the lambda expression in WithMany.

    Hope this help


    thierry
    Thursday, December 1, 2011 9:23 AM
  • Sorry alaatm, I overlooked your title and misread your post...

    But as far as I know, Alans answer that it isn't supported is what I have seen too. And that my answer is the closest way to a solution.

    I am sorry that I cant give you any better answer.


    --Rune

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful" if the post helped you to a solution of your problem.
    Thursday, December 1, 2011 11:58 AM
  • Thank you all for responding. I guess this is just not supported atm. Hopefully, we can do such mapping in a future release just like we can do this kind of mapping in NHibernate.
    Thursday, December 1, 2011 4:37 PM