I am using Database First approach and I have created model from a database. Now I have a datagrid view in my Winforms app, that is bound to a binding source. And all that works fine (an appropriate data is shown in datagrid view). Now the problem is, how to add a computed property that consists of two values (already found in db) ? For an example:
Lets say that I have a table user (id, username, first_name, last_name, user_type) but I want to have different columns in my bound datagrid view, and I want to have these columns:
username, full name, type
where "full name"
is what would I get with first_name + " " + last_name
.
I guess I can't just modify a model class manually like this:
public string FullName
{
get
{
return FirstName + " " + LastName;
}
protected set {}
}
because this class is generated automatically , and my code will be deleted each time a generate models from an existing database (when I make some change), so this is not the real option...
Actually, I solved this by using partial class functionality:
I have created another file that contains another portion of my User model class (with my additional properties) and everything went just fine.
namespace User.Model
{
public partial class User
{
public string FullName
{
get
{
return (this.firstName + " " + this.lastName;
}
protected set { }
}
}
}
Now when I generate model classes, this new file is not affected by EF. Also this new field is correctly shown by datagrid view...
I still cant add comments, so I will have to do it this way.
Regarding your approach, why don't you create a data transfer model that you will bind to the data grid view?
With this approach, your new model will have the needed property FullName and you can show this in your grid view. You database entity model will remain the same. With this, you have decoupled the database model from the view model and achieved what you wanted.
UPDATE:
/// <summary>
/// Assuming this is the EF model, generated with the database first approach. We leave it as is.
/// </summary>
public class UserEntityModel
{
public int Id { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int UserType { get; set; }
}
/// <summary>
/// This model represents your grid presentation specific data. As you can see, we have the fields
/// that we will show. This is the new DTO model
/// </summary>
public class UserGridViewModel
{
public string UserName { get; set; }
public string FullName { get; set; }
public int UserType { get; set; }
}
/// <summary>
/// This method demonstrates the retrieving and model to model mapping.
/// </summary>
public UserGridViewModel GetUser(int userId)
{
//retrieve the UserEntityModel
var efObject = _context.User.Where(user => user.Id == userId).SingleOrDefault();
if (efObject == null) {
return null;
}
// construct the new object, set the required data
return new UserGridViewModel()
{
UserName = efObject.UserName,
UserType = efObject.UserType,
FullName = $"{efObject.FirstName} {efObject.LastName}"
};
}
Additional explanation:
Let's assume that UserEntityModel
is your database first generated data model. we will leave it as is.
We will create a second model, UserGridViewModel
that contains data only that you will show in your grid. This is the DTO model.
The GetUser Method should conceptually demonstrate the usage of the first (ef model) and then the second (DTO) model. We retrieve the data from the database, we construct the DTO model and pass it to the grid.
You can find more information here and here.
Hope this helps, cheers and happy coding!