实体框架代码首次迁移与接口

时间:2015-11-17 05:06:05

标签: c# entity-framework ef-migrations

我正在尝试使用Attribute / annotations方法运行EF代码优先迁移,并将接口作为属性类型。我们使用接口构建了一个完整的基础架构,并使用它们来实现具体的类并希望启用迁移。 EF似乎没有正确关联外键关系。有没有办法纠正这个?

以下是一个例子:

我有一个IStateProvince接口如下:

 public interface IStateProvince
{

    string Abbreviation { get; set; }

    string Name { get; set; }

    ICountry Country { get; set; }

}

我还有一个ICountry接口,如下所示:

public interface ICountry
{

    string Name { get; set; }

    [MaxLength(2)]
    string TwoLetterIsoCode { get; set; }

    [MaxLength(3)]
    string ThreeLetterIsoCode { get; set; }

    int NumericIsoCode { get; set; }

    List<IStateProvince> StateProvinces { get; set; }
}

我已经创建了具体的实现,如下所示:

[Table("TypeData.Country")]
public class Country : BaseSqlEntity, ICountry
{

    [Required, MaxLength(250)]
    public string Name { get; set; }

    [Required]
    public string TwoLetterIsoCode { get; set; }

    [Required]
    public string ThreeLetterIsoCode { get; set; }

    public int NumericIsoCode { get; set; }

    public virtual List<IStateProvince> StateProvinces { get; set; }

}

州政府如下:

[Table("TypeData.StateProvince")]
public class StateProvince : BaseSqlEntity, IStateProvince
{

    [Required, MaxLength(3)]
    public string Abbreviation { get; set; }

    [Required, MaxLength(250)]
    public string Name { get; set; }

    public Guid CountryId { get; set; }

    [ForeignKey("CountryId")]
    public virtual ICountry Country { get; set; }

}

您看到的BaseSqlEntity如下:

public class BaseSqlEntity
{
    [Key]
    public Guid Id { get; set; }

    public DateTime DateCreatedUtc { get; set; }

    public DateTime DateModifiedUtc { get; set; }

    public BaseSqlEntity()
    {
        DateCreatedUtc = DateModifiedUtc = DateTime.UtcNow;
        Id = Guid.NewGuid();
    }

}

我在上下文中添加了dbsets,如下所示:

public DbSet<Country> Countries { get; set; }
public DbSet<StateProvince> StateProvinces { get; set; }

运行迁移后,我得到以下内容:

public override void Up()
    {
        CreateTable(
            "TypeData.Country",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Name = c.String(nullable: false, maxLength: 250),
                    TwoLetterIsoCode = c.String(nullable: false),
                    ThreeLetterIsoCode = c.String(nullable: false),
                    NumericIsoCode = c.Int(nullable: false),
                    DateCreatedUtc = c.DateTime(nullable: false),
                    DateModifiedUtc = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "TypeData.StateProvince",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Abbreviation = c.String(nullable: false, maxLength: 3),
                    Name = c.String(nullable: false, maxLength: 250),
                    CountryId = c.Guid(nullable: false),
                    DateCreatedUtc = c.DateTime(nullable: false),
                    DateModifiedUtc = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.Id);

    }

正如您将注意到的,没有生成外键关系,因为它无法以某种方式将ICountry与其实现Country相关联。

如果我将类型从ICountry更改为Country并注释界面,它可以正常工作并正确生成关系。

有解决方法吗?任何帮助将非常感谢。我们使用我们希望使用的界面构建了大量可重用的体系结构,但似乎这可能是一个显示阻止。

1 个答案:

答案 0 :(得分:4)

您仍然可以使用这些界面 只需要在具体类中实现接口属性,如下所示。

[Table("TypeData.Country")]
public class Country : BaseSqlEntity, ICountry
{

    [Required, MaxLength(250)]
    public string Name { get; set; }

    [Required]
    public string TwoLetterIsoCode { get; set; }

    [Required]
    public string ThreeLetterIsoCode { get; set; }

    public int NumericIsoCode { get; set; }

    public virtual List<StateProvince> StateProvinces { get; set; }

    List<IStateProvince> ICountry.StateProvinces
    {
        get
        {
            return StateProvinces.ToList<IStateProvince>();
        }

        set
        {
            StateProvinces = value.ToList().ConvertAll(o => (StateProvince)o);
        }
    }
}

[Table("TypeData.StateProvince")]
public class StateProvince : BaseSqlEntity, IStateProvince
{

    [Required, MaxLength(3)]
    public string Abbreviation { get; set; }

    [Required, MaxLength(250)]
    public string Name { get; set; }

    public Guid CountryId { get; set; }

    [ForeignKey("CountryId")]
    public virtual Country Country { get; set; }

    ICountry IStateProvince.Country
    {
        get
        {
            return Country;
        }

        set
        {
            Country = (Country)value;
        }
    }
}

希望这可以解决您的问题。