1

是否可以在不符合约定要求的数据库上使用 fluent api 配置一对一关系?下面我为您提供数据库和生成模型的示例。请注意,除了主键之外,表不定义任何约束和索引。

表:

create table Person (
   PersonKey int primary key
)

create table Address (
   AddressKey int primary key,
   owner int not null // normally should be foreign key to Person
)

从 db 生成的代码优先模型:

public partial class Person
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int PersonKey { get; set; }
}

public partial class Address
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int AddressKey { get; set; }

    public int Owner { get; set; }
}

为了能够从 Address 导航到 Person,将导航属性添加到 Address 类:

public partial class Address
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int AddressKey { get; set; }

    public int Owner { get; set; }

    public virtual Person Person { get; set; }
}

如果程序尝试执行此查询:

var Addresss = context.Addresss.Include(x => x.Person).ToList();

运行时引发异常:“列名 'Person_PersonKey' 无效”。因为上下文没有配置任何自定义映射,它会尝试按约定查找外键,但 Owner 属性不符合约定要求,因此出现异常。所以需要添加映射。如果 Person 和 Address 之间的关系是一对多的,我们可以添加这样的配置:

modelBuilder.Entity<Address>()
            .HasOptional(x => x.Person)
            .WithMany()
            .HasForeignKey(x => x.Owner);

并且上面定义的查询将正确执行。但是,如果 Person 类将具有指向 Address 的导航属性,那么我们将具有双向的一对一关系怎么办:

public partial class Person
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int PersonKey { get; set; }

    public virtual Address Address { get; set; }
}

所以上面的配置将不起作用,我的问题是,是否可以在不更改数据库和属性名称的情况下对其进行配置,如果是的话,只需要使用 fluent api 应用什么配置?

4

1 回答 1

1

这是我建议的代码,希望我理解正确!

public partial class Person
{
    public int PersonKey { get; set; }

    public Address Address {get;set;}
}

public partial class Address
{
    public virtual Person Person { get; set; }

    public int PersonId { get; set; }

    public string AddressInfo {get;set;}
}

 modelBuilder.Entity<Person>() 
             .HasKey(a => a.PersonKey); 

 modelBuilder.Entity<Course>()
             .Property(c => c.CourseId)
             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

 modelBuilder.Entity<Address>() 
             .HasKey(a => a.PersonId); 

 modelBuilder.Entity<Person>() 
             .HasRequired(p => p.Address) 
             .WithRequiredPrincipal(a => a.PersonId);
于 2015-04-13T13:21:16.057 回答