C# 首先使用EF代码映射单向关系

C# 首先使用EF代码映射单向关系,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,首先,我对EF代码相当陌生,这可能(希望如此!)是一个简单的问题 我在人和地址之间有一种简单的关系: People ------ PersonID Name Address ------- AddressID Address1 PersonID 大多数时候,我在我的人员表中都有AddressID;但是这个数据库有点“向后”,因为它引用了PersonID。在我的代码中,我处理Person对象并希望获得它们的关联地址。关系可以是一个人有很多地址,但总是1:1。(这是第三方数据库-我无法控制架构。

首先,我对EF代码相当陌生,这可能(希望如此!)是一个简单的问题

我在人和地址之间有一种简单的关系:

People
------
PersonID
Name

Address
-------
AddressID
Address1
PersonID
大多数时候,我在我的人员表中都有AddressID;但是这个数据库有点“向后”,因为它引用了PersonID。在我的代码中,我处理Person对象并希望获得它们的关联地址。关系可以是一个人有很多地址,但总是1:1。(这是第三方数据库-我无法控制架构。)

我如何在代码中首先建立关联人员和地址的关系?我正在使用fluentapi,但是如果两个实体中都没有密钥,我看不到设置它的方法。理想情况下,我希望我的实体设置如下:

Person { 
 public int PersonID {get;set;}
 public string Name {get;set;}
 //other person properites

 //navigation property
 public Address Address {get;set;}
}

Address {
 public string Address1 {get;set;}
 //other properties for address

 //navigation property
 public Person Person {get;set;}
}
我尝试了几种方法来配置关系,但总是出错。我曾尝试将Address类定义为复杂类型,但由于它是一个单独的表,这能起作用吗?此外,我还尝试使用hasportional和withoptionaledependent,但都没有用

所以,关于如何最好地配置我的EF CF逻辑以允许Address成为Person中的一个实体的任何想法

非常感谢您的任何建议或帮助

更新 我尝试了下面马克的建议,但我得到了一个不同的错误。(见我的评论)

“我的地址”实体设置将PersonID设置为实体键:

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

modelBuilder.Entity<Address>()
 .Property(a => a.PersonID)
 .HasColumnName(<my real column name>);
modelBuilder.Entity()
.HasKey(a=>a.PersonID);
modelBuilder.Entity()
.Property(a=>a.PersonID)
.HasColumnName();

因此,数据库中实体的键是PersonID,但它也是FK返回给Person。这是造成问题的原因吗?(再说一遍,不是我的DB-它是第三方。)非常感谢您的帮助。谢谢

你确定你想要的是一对一的关系吗

这种关系可能是一个人有很多地址,但它是 总是1:1。(这是第三方数据库-我无法控制架构。)

这意味着您实际上想要一个1:多的关系,对吗

也就是说,我认为导航集合是将地址映射到Person对象的理想方式:

Person { 
 public int PersonID {get;set;}
 public string Name {get;set;}
 //other person properites

 //navigation property
 public virtual ICollection<Address> Addresses {get;set;}
}
Person{
公共int PersonID{get;set;}
公共字符串名称{get;set;}
//他人财产
//导航属性
公共虚拟ICollection地址{get;set;}
}
这里是相应的Fluent(假设您有一个映射到address的PersonID,您在描述DB时会这样做,但不在代码中)

modelBuilder.Entity()
.HasMany(p=>p.address)
.WithRequired(a=>a.Person)
.HasForeignKey(a=>a.PersonID);

我根据马克的建议算出了

modelBuilder.Entity<Person>()
  .HasOptional<Address>(p => p.Address)
  .WithRequired(a => a.Person);

一旦我做到了这一点,当我需要的时候,我就使用延迟加载从Person那里获取地址信息,这一切都很有效。谢谢大家的帮助

谢谢你的回答。我没有尝试过1:many设置。当我做了您建议的更改时,我得到了一个不同的错误-
多重性在关系“Person\u Addresses”中的角色“Person\u Addresses\u Target”中无效。因为依赖角色引用键属性,所以依赖角色的多重性上限必须为“1”。
在我的设置中,地址表的PK是PersonID,我在model builder设置中将此设置作为实体键。啊,我明白了-我误解了您的设置,我认为AddressId是表的PK。也许会更有用?
modelBuilder.Entity<Person>()
  .HasOptional<Address>(p => p.Address)
  .WithRequired(a => a.Person);
_context.Configuration.ProxyCreationEnabled = false;