Creating a computed property with Entity Framework

2019-08-23 03:04发布

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...

2条回答
欢心
2楼-- · 2019-08-23 03:33

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...

查看更多
成全新的幸福
3楼-- · 2019-08-23 03:33

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!

查看更多
登录 后发表回答