Full custom properties in EF - entity-framework

Using EF with Winforms in C#. I’d like to add full custom properties to our entities, using partial classes. All entities already have partial classes with validation stuff and some more so I’d just add the properties that I need. By full property I mean property with getter and setter so not just a computed/readonly property. I want to this mostly to get around working directly with some DB mapped properties which are badly designed or have other problems.
For example, one case would be like this:
// entity class, generated
public partial class Customer
{
public string Spot {get;set}
}
// partial class, manually changed
public partial class Customer
{
public int? xxxSpot
{ get { return Int32.Parse(Spot.Trim()); } // some code omitted
{ set { Spot = value.ToString().PadLeft(5); }
}
So my custom properties will be built around existing, DB mapped properties of the entity. I’d like to use these custom properties like normal ones, ie to bind them to UI controls and so on. I’ve tried one and so far it works great.
Is this a good idea? If not, why ? And what else should I consider when doing this?

You have answered your own question - it works and there is no reason why to not do that. If you want to improve design of your entities you can even try to change visibility of your mapped properties to ensure that other classes must use only your custom properties with additional logic.

Related

Xamarin + Prism: bubble property change events from hierarchical model / view model or ...?

I've been trying to find the correct approach for this problem I got, using Prism with Xamarin Forms:
I've a model class, Customer, that contains another class, Address as a property. In my view, I show fields from both objects. I would like to have a "save" button, that only gets enabled after you've made some changes to those models.
Now, the button is bound to a Command, with the corresponding CanSave() function, as is normal with DelegateCommands. I'm trying to find an approach where I can end up with a single IsDirty property on my view model, that gets to "true" after any changed to the underlying models.
The MVVM approach
First thing I thought was the "purist" mvvm approach. A "flat" view model, with properties for each visual element, implemented as a Prism BindableObject, where each getter/setter gets/sets values from/to the underlying model classes.
That failed though, since SetProperty<> has a ref parameter, where I can't use properties from my models.
The over-engineered approach [?]
Second thing I thought was that, if my inner models were observables themselves, I could listen for changes from all of them, throughout the tree. Which opens up a whole new world of issues. Do I register property change listeners in my View model ? Do I make inner models observables, and have the parents listen for change events on their children and propagate that ?
Won't that observable models approach quickly become event handler hell ?
The simplest thing
And last, the simplest thing possible. I have a flat observable ViewModel, that only reads/writes values to/from the actual inner hierarchical model upon read & save
What do you guys think ?
Maybe I didn't understand your question right, but I'm wondering why you limit yourself to such a small helper function like SetProperty. It has 4 Lines of code. All it does is checking for equality, setting a value and raising an event.
You could easily create another helper function like this.
MyBindableBase
protected virtual bool SetProperty<T>(Func<T> get, Action<T> set, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(get(), value)) return false;
set(value);
OnPropertyChanged(propertyName);
return true;
}
Model
class Model
{
public string Property { get; set; }
}
ViewModel
class ViewModel : BindableBase
{
private Model Model { get; set; }
public string Property
{
get { return Model.Property; }
set { SetProperty(() => Model.Property, x => Model.Property = x, value); }
}
}
I think you can shorten the usage, if you introduce some naming rules for the mapping and/or use reflections.
Well, in the end I went for option 3, the simplest thing I could do.
I was leaning towards returning properties from my model, which would be easy, and using the nullable [?.] syntax it would be null-safe too, but I found that at times I'll have to wrap the actual model properties with something that is more UI-friendly, exposing more/different properties than my actual DB model classes.
So, I went for that, until some other complexity forces me to change my mind again :)
Thanks a lot #Sven-Michael Stübe and #adminSoftDK for the help

What is the best way to prevent updating on specific fields in Entity Framework

Im writing an web application with MVC using Entity Framework for my backend logic. My problem is that I have an entity that has certain fields that should never be changed on an update. I am not really sure what the best way to solve this problem would be. There is going to be a lot of data processed in my application, so I cant afford to just hack up a solution.
Is it possible to just define the fields as readonly in the POCO entities ? Or should I write and entity framework extension class that validates all updates. Could it be done in the mapping files between EF and the actual database?
I am relatively new with EF, so I hope some of you might be able to give me some pointers!
Thanks!
If you are using .NET 4.5 and EF 5 (i.e. MVC 4), you can simply set IsModified = false on the individual properties in question. This has the benefit of sticking close to the default out-of-the-box MVC conventions.
For example, if you have a CreatedBy field that shouldn't be touched when the record is updated, use the following in your controller:
[HttpPost]
public ActionResult Edit(Response response)
{
if (ModelState.IsValid)
{
db.Entry(response).State = EntityState.Modified;
db.Entry(response).Property(p => p.CreatedBy).IsModified = false;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(response);
}
Note that the IsModified line is the only change from the default controller action.
You MUST put this line AFTER setting .State = EntityState.Modified (which applies to the record as a whole and adds the record into the db context).
The effect is that EF will not include this column in the SQL UPDATE statement.
I am still (very) shocked that there are no [InsertOnly] or [UpdateOnly] attributes similar to [ReadOnly]. This seems like a major oversight by the MVC team. Am I missing something?
I'm not fully satisfied with this solution because it's a hack: You're telling EF that no change was made when what you really mean to say is "HANDS OFF". It also means that you have to use this code anyplace where the field could be updated. It would be better to have an attribute on the class property.
(Apologies for posting to an older thread, but I've not see this solution anywhere else. ViewModels are robust but a lot of work, and EF was supposed to make things easier, not harder...)
Well I would advice against ever using the EF classes in the View. You're best bet is to construct ViewModel classes and use Automapper to map them from the EF classes.
When you are updating records in the database though, you can control which fields in the ViewModel are used to update the existing fields in the EF class.
The normal process would be:
Use the Id to get the latest version of the existing object out of the database.
If you are using optimistic concurrency control then check that the object has not been updated since the ViewModel was created (so check timestamp for example).
Update this object with the required fields from your ViewModel object.
Persist the updated object back to the database.
Update to include Automapper examples:
Let's say your POCO is
public class MyObject
{
public int Id {get;set;}
public string Field1 {get;set;}
public string Field2 {get;set;}
}
and Field1 is the field you don't want updating.
You should declare a view model with the same properties:
public class MyObjectModel
{
public int Id {get;set;}
public string Field1 {get;set;}
public string Field2 {get;set;}
}
and Automap between them in the constructor of your Controller.
Mapper.CreateMap<MyObject, MyObjectModel>();
you can if you wish (although I prefer to do this manually, automap the other way too:
Mapper.CreateMap<MyObjectModel, MyObject>().ForMember(dest=>dest.Field1, opt=>opt.Ignore());
When you are sending date to your website you would use:
var myObjectModelInstance = Mapper.Map<MyObject, MyObjectModel>(myObjectInstance);
to create the viewModel.
When saving the data, you'd probably want something like:
public JsonResult SaveMyObject(MyObjectModel myModel)
{
var poco = Mapper.Map<MyObjectModel, MyObject>(myModel);
if(myModel.Id == 0 )
{
//New object
poco.Field1 = myModel.Field1 //set Field1 for new creates only
}
}
although I'd probably remove the exclusion of Field1 above and do something like:
public JsonResult SaveMyObject(MyObjectModel myModel)
{
var poco;
if(myModel.Id == 0)
{
poco = Mapper.Map<MyObjectModel, MyObject>(myModel);
}
else
{
poco = myDataLayer.GetMyObjectById(myModel.Id);
poco.Field2 = myModel.Field2;
}
myDataLayer.SaveMyObject(poco);
}
note I believe that best-practise would have you never Automap FROM the ViewModel, but to always do this manually, including for new items.
I just asked a very similar question, and I believe the answer to that one may help out a lot of folks who stumble across this one as well. The OP mentions that these are fields that should never change, and using PropertySaveBehavior.Ignore ensures this. With the existing answers to this question, you need to make custom save methods or introduce mapping where it might not make sense. By setting the AfterSave property behavior instead, you can prevent this from being possible in EF altogether.
In my project, I am generically accessing a property that is on an abstract class so I have to set it like this:
MyProperty.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
If you're accessing it directly on a known class, you'd use this:
...
.Property(e => e.YourProperty)
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);

Single Page Application, upshot.js, DbContext and DbDataController : Only Entity Models are supported?

When using the examples for Single Page Application, I've the following TodoItem controller:
public partial class MVC4TestController : DbDataController<MVC4TestContext>
{
public IQueryable<TodoItem> GetTodoItems()
{
return DbContext.TodoItems.OrderBy(t => t.TodoItemId);
}
}
Question 1:
It seems that only EntityModels are supported ?
When using a real ViewModel (model only used for the Views, not not used as 1:1 mapping to database entity), the DbDataController does not support this.
Also using Linq.Translations or PropertyTranslator does not seem to work, see this code extract:
private static readonly CompiledExpressionMap<TodoItem, string> fullExpression =
DefaultTranslationOf<TodoItem>.Property(t => t.Full).Is(t => t.Title + "_" + t.IsDone);
public string Full
{
get
{
return fullExpression.Evaluate(this);
}
}
Question 2:
What is the recommended design when using SPA, DBContext and ViewModels ?
As far as I know so far is - it instists on the usage of "real" model classes bound to DbContext.
I have the same problem as you - I need to use my own DTO objects which are "flat".
The Json serialisation is currently not able to serialize data which has parent references in child objects (cyclic references). Usually I do not need the entity tree anyways so I created smaller classes which fits perfectly to the view.
I tried to use a normal Controller with JsonResult and parsed the returned model into ko.mapping.fromJS after retrieved the data. Thats working fine. But - you have to take care of all the nice stuff the MVC4 generated viewmodels are already dealing with (like creating navigation, etc.).
Maybe someone finds a workaround to "fake" a DbContext with DTO data.

Model View Presenter - how to implement complex Properties in an IView interace

I am finding it difficult understanding how best to implement 'IView' interface properties which are not simple types, and was wondering how others approach this in a Model View Presenter application.
The articles i've read are really good but none of them seem to approach more complex Views where you have List<> properties which are of an interface type which represent a class in your domain model, i.e. IPerson, or IName etc.
I will try to outline a scenario as briefly as i possibly can.
Presume i have a requirement for a View to ultimately persist a list of names, each consisting of 3 properties 'Forename', 'Surname', and 'Title'.
Typically i will have a domain model with a class called 'Name' with the 3 properties. This domain model will implement an Interface (in a separate 'Interfaces' class Library) called 'IName'.
Now in the 'Views' namespace in my 'Interaces' library i have an interface called 'IViewNames'. This is the view interface which any view which wants to ultimately persist the list of names will implement.
How to define this 'IViewNames' interface puzzles me. If i give it a property like so:
public List<IName> Names {get;set;}
then my implementing concrete view will ultimately have a complex property 'Names' which will need a 'getter' which loops through the fields on the View, somehow instantiate an instance of 'IName', set its properties, add to a List, before returning the List. The 'setter' will be just as complex, receiving a list of 'INames' and iterating through them setting fields on the View.
I feel like this is breaking one of the major goals of the MVP approach, which is being able to thoroughly test the application code without any concrete View implemntations. After all, i could easily write a presenter which looks at the 'View.Names' property and sends it on to a Service Layer, or set the 'View.Names' property when receiving a list of 'Name' objects back from the Service Layer. I could easily write a lot of tests which ensure everything works, everything except from that COMPLEX property in the View.
So my question is, how do others approach IView properties which are not simple types, but are in fact types of your domain model? (well types of interfaces which represent your domain model, as i clearly dont want a reference from my Presentation Layer to my Domain Model layer).
I'm more than certain there is a known technique to achieving this in an elegant way, which adheres to the Model View Presenter goals, more than my example approach does.
Thanks in advance for any help people.
I have not worked much on the MVP design pattern but will surely try my hands on it.
Approach1 : DataBinding
In this case you can also create individual properties in IView and bind these properties in presenter to the model properties. This way, your view will not get complicated. The experience is fast and seamless as the values from UI can be directly used in model. Changing the property value in model will reflect in UI immedietly. You may have to use NotifyPropertyChange events for this.
Approach 2 : Complex Types
You can try creating List or Tuples to store these values and use the values in the presenter. You may have to use events or actions to reflect the value from model to view and vice versa.
Please let me know if it helped you. Thanks.
I have lifted this explanation from one of the articles I am writing on my website
Presenter to View Communication
There are two styles utilised for populating the View with data from the Presenter and Model that I have used. The only difference between them is how tightly coupled you mind your View being to the Model. For the example of this, we will have the following as our Model:
public class Person
{
public int ID { get; private set; }
public int Age { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
Public Genders Gender { get; set; }
}
Method 1: Using the Model
Now our View code:
public interface IEmployeesView
{
void ClearList();
void PopulateList(IEnumerable<Person> people);
}
And finally the Presenter:
public class IEmployeesPresenter
{
public void Display()
{
_view.ClearList();
_view.PopulateList(_model.AllEmployees);
}
}
This method of population produces a link between the Model and the View; the Person object used as a parameter in PopulateList.
The advantage of this is that the concrete implementation of the IEmployeesView can decide on what to display in its list of people, picking from any or all of the properties on the Person.
Their are two disadvantages of this method. The first is that there is nothing stopping the View from calling methods on the Person, which makes it easy for lazy code to slip in. The second is that if the model were to change from a List<Person> to a List<Dog> for instance, not only would the Model and the Presenter need to change, but so the View would too.
Method 2: Using Generic Types
The other method population relies on using Tuple<...>, KeyValuePair<,> and custom classes and structs:
Now our View code:
public interface IEmployeesView
{
void ClearList();
void PopulateList(IEnumerable<Tuple<int, String> names);
}
And finally the Presenter:
public class IEmployeesPresenter
{
public void Display()
{
var names = _model.AllEmployees.Select(x => new Tuple<int, String>(x.ID, x.FirstName + " " + x.LastName));
_view.ClearList();
_view.PopulateList(names);
}
}
The advantages of this method of population is that the Model is free to change without needing to update the View, and the View has no decisions to make on what to display. It also prevents the View from calling any extra methods on the Person, as it does not have a reference to it.
The down sides to this method, are that you loose strong typing, and discoverability - It is quite obvious what a Person is but what a Tuple<int, String> is less obvious.

MVC2 Action to handle multiple models

I've been looking around for an answer to this, which I can't believe hasn't been asked before, but with no luck I'm attempting here.
I have a signup form which differs slightly based upon what type of participant the requester is. While writing tests for the solution, I realized that all actions did the same things, so I'm attempting to combine the actions into one using a strategy pattern.
public abstract class BaseForm { common properties and methods }
public class Form1 : BaseForm { unique properties and overrides }
....
public class FormX : BaseForm { unique properties and overrides... in all about 5 forms }
Here is the combined action:
[ModelStateToTempData, HttpPost]
public ActionResult Signup(int id, FormCollection collection)
{
uiWrapper= this.uiWrapperCollection.SingleOrDefault(w => w.CanHandle(collection));
// nullcheck on uiWrapper, redirect if null
var /*BaseForm*/ form = uiWrapper.GetForm(); // Returns FormX corresponding to collection.
this.TryUpdateModel(form, collection.ToValueProvider()); // Here is the problem
form.Validate(this.ModelState); // Multi-Property validation unique to some forms.
if (!this.ModelState.IsValid)
return this.RedirectToAction(c => c.Signup(id));
this.Logic.Save(form.ToDomainClass());
return this.RedirectToAction(c => c.SignupComplete());
}
The problem I'm having is that TryUpdateModel binds only the common properties found in BaseForm. My previous code used public ActionResult FormName(int id, FormX form) which bound properly. However, I did some testing and discovered that if I replace var form with FormX form the form binds and everything works, but I'm back to one action per form type.
I'm hoping to find a way to get this to bind properly. form.GetType() returns the proper non-base class of the form, but I'm not sure of how to grab the constructor, instantiate a class, and then throw that into TryUpdateModel. I know that the other possibility is a custom ModelBinder, but I don't see a way of creating one without running into the same FormBase problem.
Any ideas or suggestions of where to look?
I was trying to do something similar to Linq, I was trying to create a class that would inherit some standard fields (ID, etc). I found that the default Linq engine would only use fields from the instantiated class, not from any inherited classes or interfaces.
To construct a Type simply use code like:
var form = Activator.CreateInstance(uiWrapper.GetForm());
I figured it out!
Erik's answer wasn't the solution, but for some reason it made me think of the solution.
What I really want form to be is a dynamic type. If I change this line:
dynamic form = uiWrapper.GetForm();
Everything works :)
On top of that, logic.Save(form.ToDomainClass()) also goes directly to Save(DomainTypeOfForm) rather than Save(BaseDomainForm) so I can avoid the headache there as well. I knew that once I figured out the problem here I could apply the answer in my logic class as well.