提取由IDatabaseInitializer中的DbContext.OnModelCreating创建的配置

时间:2011-05-22 04:38:38

标签: c# ef-code-first entity-framework-4.1 unique-constraint

可以在IDatabaseInitializer.InitializeDatabase的实现中访问在DbContext.OnModelCreating实现期间创建的配置吗?给定一个DbContext实例,我无法看到如何进入该配置。

背景

我选择使用Entity Framework 4.1的代码优先功能来实现一个系统,因为它允许我支持多个数据库引擎,例如SQL Server和MySQL。像大多数应用程序一样,我需要确保某些实体具有唯一的属性。

编译其他sql语句以生成建议herehere的唯一约束没有问题。但是,我的模型变得越来越大,手工编写SQL语句很容易出错,因为它根据TPH,TPC,表名和列名对底层物理数据库模式做了几个假设。在某些情况下,如TPH,甚至可能无法添加唯一约束,并且必须使用另一种特定于数据库的方法,如唯一索引。

我已开始撰写以下内容。我们的想法是遍历配置,找到具有唯一约束的属性,并调用特定于提供者的方法来添加唯一约束。

public class UniqueAttribute : Attribute
{
    readonly List<string> _names = new List<string>();

    public UniqueAttribute(params string[] names)
    {
        _names.AddRange(names);
    }

    public IEnumerable<string> PropertyNames
    {
        get
        {
            return _names;
        }
    }
}

public class Party
{
    /* some properties, like id */
    public virtual ICollection<Address> Addresses { get; set; }
}

public class Person : Party
{
    /* some properties unique to a person*/
    [Unique]
    public string UserName { get; set; }
}

public class Address
{
    /* properties for addresses */
}

public class SampleDatabaseContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Party>();
        modelBuilder.Entity<Person>();
        modelBuilder.Entity<Address>();
    }
}

public abstract class SampleDatabaseInitializer : IDatabaseInitializer<SampleDatabaseContext>
{
    public void InitializeDatabase(SampleDatabaseContext context)
    {
        /* code to create the database if it doesn't exist */

        // TODO: Walk through the context configuration and find "unique" columns
        // TODO: For each unique column, call AddUniqueConstraint
    }

    public abstract void AddUniqueConstraint(SampleDatabaseContext context, params string[] names);
}

class MySqlSampleDatabaseInitializer : SampleDatabaseInitializer
{
    public override void AddUniqueConstraint(SampleDatabaseContext context, params string[] names)
    {
        /* MySQL specific code to add unique constraints */
    }
}

class SqlSampleDatabaseInitializer : SampleDatabaseInitializer
{
    public override void AddUniqueConstraint(SampleDatabaseContext context, params string[] names)
    {
        /* Sql Server specific code to add unique constraints */
    }
}

class OracleSampleDatabaseInitializer : SampleDatabaseInitializer
{
    public override void AddUniqueConstraint(SampleDatabaseContext context, params string[] names)
    {
        /* Oracle specific code to add unique constraints */
    }
}

非常感谢。

1 个答案:

答案 0 :(得分:1)

无法从上下文访问配置。一旦获得上下文实例配置已经编译,您就无法访问其“类”或属性。编译模型只是用于定义映射的元数据集。这些元数据不包含有关唯一属性的其他信息。

您必须在此方案中使用反射。只需从您的实体装配程序集中的所有类型,并查找标有Unique属性的属性。