为Entity Framework导航属性设置默认对象

时间:2015-11-09 00:38:54

标签: c# entity-framework entity-framework-6

是否可以为实体设置默认对象?

假设我有一个Person实体,最初没有Profile的要求。

现在我需要Profile - 但现有的实体目前没有Profile

我是否有办法在将来加载这些实体时为这些实体提供默认对象,因此使用Person实体的任何人都可以认为Profile永远不会为空且始终有一个值 - 即使它是默认值。

下面你可以看到我尝试过的东西 - 它确实创建了一个默认值 - 但即使数据库中有东西它总是返回默认对象。

  • 如果Profilenull,我想返回默认的初始化对象
  • 如果Profile 不是 null我想从数据库中返回该对象

此外 - 附加"默认"最合理的方法是什么?对象到我的dbcontext?

我如何实现这种理想的行为?

public class Person
{
    [Key]
    public int Id {get; set;}

    private Profile _profile;
    public virtual Profile Profile
    {
        get
        {
            return _profile ?? (_profile= new Profile
            {
                Person = this,
                PersonId = Id
            });
        }
        set
        {
            _profile = value;
        }

        // properties
    }
}

public class Profile
{
    [Key, ForeignKey("Person")]
    public int PersonId {get; set;}

    [ForeignKey("PersonId")]
    public virtual Person Person{ get; set; }

    // properties
}

我知道您可以初始化集合,以便它们不会为空,但我也想初始化单个对象。

2 个答案:

答案 0 :(得分:3)

使用ObjectContext.ObjectMaterialized Event

为实现后加载到上下文中的每个实体引发此事件。

在上下文的构造函数中,订阅此事件。在事件处理程序中,检查实体类型是否为Person,如果是,则为该人员创建新的配置文件。这是一个代码示例:

public class Context : DbContext
{
    private readonly ObjectContext m_ObjectContext;

    public DbSet<Person> People { get; set; }
    public DbSet<Profile> Profiles { get; set; }

    public Context()
    {
        var m_ObjectContext = ((IObjectContextAdapter)this).ObjectContext;

        m_ObjectContext.ObjectMaterialized += context_ObjectMaterialized;

    }

    void context_ObjectMaterialized(object sender, System.Data.Entity.Core.Objects.ObjectMaterializedEventArgs e)
    {

        var person = e.Entity as Person;

        if (person == null)
            return;

        if (person.Profile == null)
            person.Profile = new Profile() {Person = person};

    }
}

请注意,如果您提交更改,新配置文件将保存回数据库。

答案 1 :(得分:-1)

您只需要实施IdProfile&#39; get&#39;个人财产,必须设置个人资料ID。

让我试着用流利的API来展示你:

public class Person
{
    public int Id {get; set;}
    private int _idProfile;
    public int IdProfile {
        get{
            return _idProfile == 0 ? DEFAULT_PROFILE_ID : _idProfile;
        }
        set{
            _idProfile  = value;
        }
    }

    public virtual Profile @Profile;
}

public class Profile
{
    public int Id {get; set;}
    public virtual ICollection<Person> Persons { get; set; }
}

/* MAPPING */

public class PersonMap : EntityTypeConfiguration<Person>
{
    this.HasRequired(t => t.Profile)
            .WithMany(t => t.Persons)
            .HasForeignKey(d => d.IdProfile);
}