32

Suppose I have an Employee object with the following properties:

string Name { get; }
float Hours { get; }
float Wage { get; }

I want to add a property, Salary, which equals Hours * Wage. In an ordinary business object, I would simply code that up in the property, but this would presumably wiped out if the class needed to be regenerated.

Is there an EF standard way to implement this without going through the trouble of mapping it to a database entity?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Chris B. Behrens
  • 6,255
  • 8
  • 45
  • 71

5 Answers5

53

Indeed. Create a separate file, for instance, EmployeeExtension.cs.

In this file, place the following code:

public partial class Employee
{
    public decimal Salary
    {
        get { return Hours * Wage; }
    }
}

LINQ to SQL and Entity Framework classes are generated with the partial keyword to allow you to split the definition over many files, because the designers knew that you will want to add members to the class that aren't overwritten by continually autogenerating the base source file.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
JoshJordan
  • 12,676
  • 10
  • 53
  • 63
  • Excellent! I'd been creating shadow classes, which was utterly painful. Much thanks – Chris B. Behrens Jul 15 '09 at 21:28
  • 1
    This doesn't seem to work with Linq to Entities since it's not defined in the actual data model. Is there a way to define a calculated field in the *.edmx? – AaronLS Jan 11 '10 at 19:50
  • Can you be more specific than "doesn't seem to work"? If you're referring to columns with computed values at the database level, thats a whole different beast. – JoshJordan Jan 14 '10 at 00:10
  • 5
    This also does not work with OData (WCF Data Services). That is because it is not in the edmx. (Only the EDMX is read for OData.) – Vaccano Oct 07 '11 at 20:01
  • 3
    The property will work once you go into a local context (aka .ToList()). There are obvious drawback however. You cannot use this field to filtering efficiently as it requires you to request the entire data before doing such an operation. In huge database scenarios, this can be very costly and unacceptable. – Pluc Aug 19 '14 at 13:19
7

If i remember correctly the classes created by the EF are partial. So you could possibly add another file containing another partial class (same namespace, same classname of course) which than implements the property

public single Salary
{
   get
   {
       return this.Hours * this.Wage;
   }
}

Should do the trick (if those singles are not nullable, mind you!)

Argo
  • 201
  • 3
  • 5
6

I was not able to get 'Argo's answer to work initially. After a little playing around I noticed that if i decorated the property (as in WCF), which the following attribute, all worked fine.

[global::System.Runtime.Serialization.DataMemberAttribute()]

As per 'Argo's instructions create a separate file, (for example EmployeeExtension.cs). this should be marked partial as described.

In this file, place the following code:

public partial class Employee 
{
   [global::System.Runtime.Serialization.DataMemberAttribute()]       
   public decimal Salary     
   { 
      get { return Hours*Wage; } 
   } 
}  

Hope this helps….

Amit
  • 165
  • 1
  • 5
  • 18
Philip.ie
  • 1,506
  • 1
  • 17
  • 19
5

You can implement the property in the entity class. The entity framework will generate partial classes allowing you to add members to the class. Add a class like this to your code:

public partial class Employee {
  public Single Salary {
    get { return Hours*Wage; }
  }
}
Martin Liversage
  • 104,481
  • 22
  • 209
  • 256
4

This wasn't working for me with Entity Framework 5. The solution for me was to simply use the [NotMapped] attribute. For more info see Code First DataAnnotations

Elijah W. Gagne
  • 2,801
  • 4
  • 31
  • 29