How to notify ViewModel on a change in Model (EntityObject) calculated property - entity-framework

I have added a calculated property to my Model (Entity Framework autogenerated class). How do I notify the ViewModel of any changes on this property? The calculated property sits in my partial class so the class is an EntityObject.
The EF EntityObject class has ReportPropertyChanged on every autogenerated property but how do I do it with my own calculated properties? If I try to use it, I get an ArgumentException: The property 'xxxxxx' does not have a valid entity mapping on the entity object.

From what I can understand, you have extended an EF entity to add a calculated property and you want to update the UI accordingly when your calculated property changes.
In that case, implement INotifyPropertyChanged on your partial class and then call OnPropertyChanged("propertyName") when your calculated property is updated.

Related

Any Point to the DbSet Property Name?

public DbSet<Lecture> Lectures{ get; set; }
Does the property name here matter at all? It seems that if I want to use the model, I use "Lecture". The generated table is just a plural of whatever is in <>, e.g., if I understand correctly, I can change "Lectures" to "Leprechauns" and my table will still be called "Lectures" based on <Lecture> and I will use context.Lectures to select from it. Does the property name have any point?
I didn't find the answers in this tutorial or on msdn.
Edit: Upon further testing - the db table name is based on the model name in the angle brackets, but to actually select from the db (in the C# code), you use the property name specified in DbSet propertyName. Still would like to hear how this works in detail.
Entity Framework builds a model of the database, where each class/model represents an entity type, and each DbSet represents a set of entities of a single type. When you declare a DbSet<T> property in your DbContext, that tells EF to include the class of type T as one of the entity types, and it automatically includes any other connected types (e.g. navigation properties) in the object graph as well.
All this to say, the name of the property itself probably doesn't matter. In fact, you could use the Fluent API to add entity types as well, not declare any DbSet properties if you wanted, in which case you'd use context.Set<T> to retrieve the DbSets. The properties are really just for convenience.
Maybe this is helpful as well: https://msdn.microsoft.com/en-us/data/jj592675.aspx
DbSet corresponds to a table or view in your database, So you will be using your DbSet's to get access, create, update, delete and modify your table data.
By the way you can remove the convention:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
The property name matters. The EF translates the name of the property into the name of the table. If the property name is not the same with the table name you'll get an error. Unless you specifically tell the builder the name of the table like this:
public void Configure(EntityTypeBuilder<Lecture> builder)
{
builder.ToTable("License");
}

Entity Framework - updating sum of related entity collection property values on parent entity

How can I effectively update the parent EntityObject property which is there to expose only the sum of the related child entity collection property? I need an update in parent any time there is a change of property value in any of the child entity.
An example: I have a parent EntityObject "Company" and a collection of related child objects "Employee". These have association in EF between each other (one Company to collection of Employees). In Employee partial class I have added a custom calculated property "Salary" and in a Company partial class I have added a custom property "TotalSalaries".
Now, if any Employee Salary property is updated to a new value, I want to immediately update the Company object property TotalSalaries value.
Whenever the Employee property changes and if then I always run a full query inside the Company object like:
TotalSalaries = Me.Employees.Sum(Function(x) x.Salary)
...that looks like a highly inefficient thing to do, especially if all custom property values in Employee class are changed by looping for example (the above query is run over and over again).
Can the property update be reflected in the parent class more efficiently?
I figured this out. On the Employee class, I can capture the original property value in a class-level PropertyChanging event:
Private Sub employee_PropertyChanging(ByVal sender As Object, ByVal e As PropertyChangingEventArgs) Handles Me.PropertyChanging
Dim propBeignChanged As String = e.PropertyName
If propBeignChanged = "Salary" Then
OriginalValue = CType(sender, Employee).Salary 'store the current value temporarily to a variable
End If
End Sub
And then I can get the new value either in a class-level PropertyChanged event or the property-specific On[Property]Changed event, calculate the difference against the temporarily stored original value and pass the difference to the parent object.
Private Sub OnSalaryChanged()
Dim diff as Double = Me.Salary - OriginalValue
'and finally pass diff to the parent object for updating its total...
End Sub
I believe this must be a much faster approach than querying the whole EntityCollection.

entity framework "composite" property?

I am using EF 4.1, code first and want a property on a customer entity built up of a constant string value and the customerId zero padded to act as a customer reference.
I might be being a bit daft but am struggling to work out how I can achieve this without
A) having to savechanges twice, once to get the Id then set my reference and save again
B) having a partial Customer class that simply provides a getter returning constant + CustomerId.Tostring("000000")
Is this "doable" with code first?
If you can change the database I would make a computed column for this. Thus, you leave it to the database to generate a reference value and it will also be available to other consumers of the database (if any).
Your Customer class will have a property like CustomerReference (string) that maps to the computed column and that is configured to have DatabaseGeneratedOption.Computed which will cause EF to read the value after inserting an object.

How to tell entity framework how to save instances of a custom type (that can be stored as a scalar)

One of my entity classes would be possible to store in a sql server
database as a BIGINT. My question is: How do I get a Entity Framework
context to know how to store and retrieve instances of my entity class?
More detail. I'm using Noda Time, which can represent a (much) wider range of
dates than can SQL or .NET datetime (AND it's a dessert topping). My Entity Class, Happening, is a wrapper around NodaTime's
Instant class. I can set a Happening from a long, and get a long from
a happening with methods like .SetFromLong(long instant) and .ToLong().
Currently I have my model working, saving classes that contain
properties of the dot net DateTime type. If instead I want to use properties
of my custom type "Happening", how do I tell Entity Framework how to save those?
If I'm reading this article about Modeling and Mapping am I on the
right track or missing something simpler?
http://msdn.microsoft.com/en-us/library/bb896343.aspx
I'm using entity framework 4.
What i recommend doing is adding 2 properties on your entity a NodaTime and a long, and exclude your NodaTime property using [NotMapped] in your EF model, then in your getter/setter update the long.
ie
public class MyEntity{
public long TimeAsLong{get;set;}
[NotMapped]
public Happening {
get{
return new Happening().SetFromLong(TimeAsLong);
}
set {
TimeAsLong = value.ToLong();
}
}
}
The effect of this will be that the long is stored in the db but you can access it on the class via NodaTime

extending an entity framework model

i want extend an entity framework model with a temporany attribute.
I need it only in a mvc form. I don't need save it in the db.
How can i do it?
Create a partial class for the entity you want to extend
e.g.
//must be in the same namespace as the Customer entity in the model
public partial class Customer
{
public string MyProperty{get;set;}
}
This property will be unmapped and you can fill it with data after you run a query or on materialization.
OR
Create a wrapper class for your entity which expose both the unmapped property and the mapped properties the properties you need in the view.