Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Change Navigation Property Names Into Meaningful Names

I'm using Database First with Entity Framework 5. We have two tables (massively simplified):

  • Addresses
    • Street
    • Town (etc.)
  • Customers
    • Name
    • BillingAddress
    • DeliveryAddress
    • AltDeliveryAddress

When we use Visual Studio to import the database into EF ("Update Model from Database"), we end up with code like this:

Customer myCustomer;
var a = myCustomer.Address;
var b = myCustomer.Address1;
var c = myCustomer.Address2;

What I want obviously is something like this:

var a = myCustomer.BillingAddress;
var z = myCustomer.BillingAddress.Street; // etc.

I could just edit the model in the designer, changing the Navigation Property to give me the correct name. However this isn't a viable solution because we rebuild the model every time we make changes to the database.

One option I've tried is creating a partial class like this (code copied from existing MyModel.Designer.cs with just the property name changed):

public partial class Customer : EntityObject
{
    [EdmRelationshipNavigationPropertyAttribute("MyModel", "FK_Customers_Addresses_BillingAddress", "Address")]
    public Address BillingAddress
    {
        get {
            return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value;
        }
        set {
            ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value = value;
        }
    }
}

However when I run this, I get the following error:

The number of members in the conceptual type 'MyModel.Customer' does not match with the number of members on the object side type 'MyNamespace.DataModel.Customer'. Make sure the number of members are the same.

I've tried using the [NotMapped()] attribute, but that hasn't made any difference. If I remove the [EdmRelationshipNavigationPropertyAttribute...] attribute then the Linq complains with the following error:

The specified type member 'BillingAddress' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Is there any other way to achieve meaningful names in the Customers object?

Here's what I want at the end:

var j = myCustomer.BillingAddress;
var k = myCustomer.BillingAddress.Street;
var l = myCustomer.BillingAddress.Town; // etc.
like image 813
andrewpm Avatar asked Nov 23 '12 12:11

andrewpm


2 Answers

You probably don't have to worry about this. After changing the property name in the model designer EF will remember the custom naming. It won't be overwritten by subsequent updates.

like image 78
Dennis Traub Avatar answered Oct 13 '22 00:10

Dennis Traub


You can add properties to your partial class that will be accessors to properties Address1, Address2 etc.

Example:

public partial class Customer : EntityObject
{
    public Address BillingAddress
    {
         get 
         {
             return this.Address;
         }
         set 
         {
              this.Address = value;
         }
    }
}

Update: It will not work with linq to entities. I'm afraid this is limitation of database first approach. It is one of the causes for us to use EF Code First. In Code First you have full control on entity mapping. (Code First means mapping in code, it is not mean that your db will be generated from this code if you don't want it).

like image 31
Kirill Bestemyanov Avatar answered Oct 12 '22 23:10

Kirill Bestemyanov