locked
Code First generation of Entities from database where PKs are GUIDs RRS feed

  • Question

  • I already have a coded object model generated using a different ORM, but am trying to generate an EF Model for used with DataServices, but have run into a snag with the way the Entities in the EDMX file when the PK's of the tables are GUIDs.  It looks like the Entities are doubling up the properties for the FK fields.  So given I have an entity called Widget with a PK called Oid which is a GUID and it's related to another Entity called Factory with the same PK functionality, the Code First modeling wizard generates the Factory entity with:

    1) a scalar Widget property of type GUID

    2) a Widget1 navigation property of type "Widget"

    Is this something that can be changed or corrected?  Is this stemming from the PK structure in the database (I've seen posts about server side PK Guids causing problems), but the relationships are being created as I would expect, so I'm not sure.  I'm also using the MS Entity Framework June 2011 CTP if this changes anything

    Friday, September 30, 2011 9:08 PM

Answers

  • Unchecking the "Include FK Columns" resolves the issue that I'm seeing.  I have to say, I'm not very impressed with the naming convension used to create the property names though.  I understand some user's needs to have the FK value (i.e. the GUID in my case) on the model in order to do things like Lazy Loading (I'm assuming, but if there are other reasons I'm interested to learn), but it would make much more sense to name the Property as <FK><FK's PK> instead of doubling up the property names where the NavigationProperty gets a 1 tacked on the end.  In other words the "Include FK column" option should generate the property name as WidgetOid instead of Widget (see below).

    public class Factory{

    public Guid Oid {get;set;}

    public Nullable<Guid> WidgetOid {get;set;}

    public virtual Widget Widget {get;set}

    }

    I just came across this post which explains the changes/rename of Independent Associations and FK Associations  and gives some good reason why the Property would be generated, but I still think the naming convention needs some serious work.

    http://blogs.msdn.com/b/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx

     

    • Edited by Christopher Hurst Thursday, October 6, 2011 4:07 PM
    • Proposed as answer by Alan_chen Tuesday, October 11, 2011 1:58 AM
    • Marked as answer by Alan_chen Friday, October 14, 2011 1:30 AM
    Thursday, October 6, 2011 3:54 PM

All replies

  • Hi Christopher,

    Welcome!

    Why don't use Id as your property name? EF will set "Widget" as the navigation name, but there is a property called "Widget", so it will append "1" after the name. I think you are using "Code Generator", actually you can use Fluent API to rename the foriegn key, you can refer here: http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-fluent-api-samples.aspx

    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.

    Monday, October 3, 2011 5:19 AM
  • I believe I may have used the wrong terms in my initial post.  I have an existing database which was built using a different ORM and I am attempting to extract the schema out into an EDMX file which can then use a TextTemplatingFileGenerator to automagically create my classes.  My problem is the EDMX file when reading the schema from the database, is generating my Entities where the FK of another Entity is listed both as a Property as well as a Navigation Property instead of only being listed once as a Navigation Property.

    So I'm getting classes generated like this:

    public class Factory{

    public Guid Oid {get;set;}

    public Nullable<Guid> Widget {get;set;}

    public virtual Widget Widget1 {get;set}

    }

    ******************************************

    When I'm expecting to get classes generated like this:

    public class Factory{

    public Guid Oid {get;set;}

    public virtual Widget Widget {get;set}

    }

    I'm not sure, but I don't think it's an issue of renaming the FK property using the Fluent API, but rather the way the the EDMX file is incorrectly reading the database schema to build the Entities.  Does this make since?

    Monday, October 3, 2011 8:49 PM
  • Hi Christopher,

    Thanks for your feedback.

    When you go the Wizard of Entity Data Model, you can ummark "Include foreign key columns in the model"

     

    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.

    Tuesday, October 4, 2011 3:06 AM
  • Unchecking the "Include FK Columns" resolves the issue that I'm seeing.  I have to say, I'm not very impressed with the naming convension used to create the property names though.  I understand some user's needs to have the FK value (i.e. the GUID in my case) on the model in order to do things like Lazy Loading (I'm assuming, but if there are other reasons I'm interested to learn), but it would make much more sense to name the Property as <FK><FK's PK> instead of doubling up the property names where the NavigationProperty gets a 1 tacked on the end.  In other words the "Include FK column" option should generate the property name as WidgetOid instead of Widget (see below).

    public class Factory{

    public Guid Oid {get;set;}

    public Nullable<Guid> WidgetOid {get;set;}

    public virtual Widget Widget {get;set}

    }

    I just came across this post which explains the changes/rename of Independent Associations and FK Associations  and gives some good reason why the Property would be generated, but I still think the naming convention needs some serious work.

    http://blogs.msdn.com/b/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx

     

    • Edited by Christopher Hurst Thursday, October 6, 2011 4:07 PM
    • Proposed as answer by Alan_chen Tuesday, October 11, 2011 1:58 AM
    • Marked as answer by Alan_chen Friday, October 14, 2011 1:30 AM
    Thursday, October 6, 2011 3:54 PM
  • Hi Hurst,

    Thanks for your suggestions. If you upgrade to EF4.1 code first, you can use Data Annotation or Fluent API to change the Navigation Name.

    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.

    Friday, October 7, 2011 7:45 AM
  • Unless I'm missing something, the Data Annotation and the Fluent API functionality works against the Code First style and not the database correct?
    Tuesday, November 29, 2011 10:19 PM
  • As I'm new to EF, I'm still learning but I am wanting to generate a similar model to my existing 3rd Party Model which is not built on POCO objects which is why I'm currently shying away from the Code First approach and instead would rather us the Database first approach to create a similar Model for use in OData feeds.  Due to the limited functionality available for customization in the EDMX Wizard used to create the model from the database, it appears that I don't have a lot of options.  At this point, I have written a simple WinForms app which can be pointed at the EDMX file and automagically go through the Conceptual Model and correct the NavigationProperty Names on the 1:M relationships to use the EntityType Name and change the and FK Property to use the EntityTypeName appended with the text "ID" or "Key" like I want.  Along with this I had to update the C-S Mappings so the FK Property name is now used.  I would highly recommend there be more flexiblity in allowing developers to automate/mass modify the Entity Model during it's creation, not just limiting them to the generation of the concrete classes using Text Templates after the fact.  The model should serve as the key goto visual document to quickly identify the framework.

    It also appears that I can't use the Fluent API on my existing POCO model as the DbContext.OnModelCreating does not support the registration of PrimaryKey properties which exist in a Base Class.

    In other words the following fails.

    modelBuilder.Entity<User>.HasKey(u => u.Id);

    public class BaseObject

    {

        public GUID Id {get; set;}

    }

    public class User : BaseObject

    {

        public string Name {get;set;}

    Thursday, December 8, 2011 4:38 PM