简体   繁体   中英

Entity Framework virtual collections initialization

I have the following classes:

public class User
{
        public Guid Id { get; set; }
        public string UserName { get; set; } 
        //... Other properties here 

        public virtual ICollection<Role> Roles { get; set; }
}

and the Role class

public class Role
    {
        public Guid Id { get; set; } 
        public string Name { get; set; } 

        public virtual User User { get; set; }
    }

I want for each User instance to have at least on Role (default role like "RegularUser" role) in the Roles collection. In the case when I make up a new User and I don't assign it any Role and add it to DB, on retrieve I should have the Roles collection empty.

Should I instantiate the Roles collection in User constructor and add there a default Role? Wouldn't this overwrite the Roles collection if there are already some roles in my DB? When exactly is the virtual collection initialized?

How should I tackle this problem?

Regards, Ionut

This is why it's my opinion that the EF class model is primarily a data access layer, not a domain layer. I would not add any default objects to persisted collections in EF classes.

Suppose you would always add a default Role when the collection is empty, eg in the getter:

public virtual ICollection<Role> Roles
{ 
    get
    {
        if (!this._roles.Any()) // initialized in the constructor
            this._roles.Add(new Role {...});
        return this._roles;
    }
    set { this._roles = value; }
}

This causes inconsistent behaviour. If EF gets User objects from the database, depending on the query it may assign a whole new collection to Roles , but it may also add items to it. For instance, Include is different than selecting user.Roles . In the latter case the default role will always be in the collections, in the former case, never . (It's a bit off topic to explain this all, and I'm not sure if I grasp all the internal machinery). Moreover, you may inadvertently save the default role to the database.

I would deal with role-less users in the authorization logic. When you evaluate a User's privileges you can always add a default role to a local collection of roles that you temporarily build in memory from the User 's roles.

If you want to display a default role, it's better to show a view model in which you can add the role.

将Factory用于任何创建对象逻辑。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM