EF 4.1 Code First - 使用非标准列名映射一对一关系 [英] EF 4.1 Code First - Mapping a one to one relationship with non standard column names

查看:243
本文介绍了EF 4.1 Code First - 使用非标准列名映射一对一关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道很多人在EF 4.1上询问一对一的关系,但是我似乎无法找到这个问题的答案。



我有这些POCO类:

  public class Contact 
{
public decimal nCont_id {get;组; }

public virtual WebsiteMembership WebsiteMembership {get;组; }
//一堆其他属性
}

public class WebsiteMembership
{
public int WebsiteMembershipId {get;组; }

public virtual联系联系{get;组;网站成员资格的主键(WebsiteMembershipId)也是一个外键,引用联系人的nCont_id。

我试图用流利的API设置它:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//这是因为非常规的列名,我必须用
modelBuilder.Conventions.Remove< NavigationPropertyNameForeignKeyDiscoveryConvention> ();

//一堆其他东西
modelBuilder.Entity< Contact>()。ToTable(contacts);
modelBuilder.Entity< Contact>()。HasKey(b => b.nCont_id); (b => b.Contact).Map(b => b.MapKey(WebsiteMembershipId))。 ;

modelBuilder.Entity< WebsiteMembership>()。ToTable(WebsiteMembership);
modelBuilder.Entity< WebsiteMembership>()。HasKey(b => b.WebsiteMembershipId);






$ b

但是当我尝试这样做时, p>

  var websiteMembership = context.WebsiteMemberships.Where(c => c.WebsiteMembershipId == 1645942).FirstOrDefault(); 

例外:


指定的模式无效。错误:(263,6):错误0019:类型中的每个
属性名称必须是唯一的。属性名称
'WebsiteMembershipId'已被定义。

这是否意味着我不能设置相同的主键EF CodeFirst上的外键?或者我在这里做错了什么?如果主键与外键不在同一列,它会工作吗?



建议非常感谢!

解决方案

我想当你定义这个映射... $ b

  modelBuilder.Entity< Contact>()
.HasOptional(b => b.WebsiteMembership)
.WithRequired(b => b.Contact)
.Map b => b.MapKey(WebsiteMembershipId));

...您隐式定义了什么是主体,什么是关系的依赖关系。显然联系人是主体,因为对于联系人, WebsiteMembership code>,它可以被存储而不需要 WebsiteMembership 。另一方的 WebsiteMembership 实体对 Contact 有一个必需的引用,这意味着它联系人



主体(联系人)是具有主键的实体,依赖( WebsiteMembership )具有外键的实体。因此,当您使用 MapKey 设置外键列的名称 WebsiteMembershipId 时,您可以为表 WebsiteMembership ,而不是联系人。但 WebsiteMembership 已经有一个名为 WebsiteMembershipId 的属性。 (我相信这是EF抱怨属性名称'WebsiteMembershipId'已经定义)。在一对多关系中,外键是 ContactId 作为一个单独的属性/列,你将不得不使用 HasForeignKey 而不是 MapKey 。但是在一对一的关系中,显然外键是主键,所以你根本不需要定义外键。

长话短说:只要删除 MapKey
$ b

 .WithRequired(b => b.Contact); 

(但现在我很好奇,如果您可以定义 int 和一个小数属性,或者如果你得到下一个错误。)


I know a lot of people is asking about one-to-one relationships on EF 4.1 but I can't seem to find an answer for this problem.

I have these POCO classes:

public class Contact
{
    public decimal nCont_id { get; set; }

    public virtual WebsiteMembership WebsiteMembership { get; set; }
    //a bunch of other properties
}

public class WebsiteMembership
{
    public int WebsiteMembershipId { get; set; }

    public virtual Contact Contact { get; set; }
}

Website membership's primary key (WebsiteMembershipId) is also a foreign key that references Contact's nCont_id.

I'm trying to set this up using the fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //This is being done because of the unconventional column names I have to live with
    modelBuilder.Conventions.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>();

    //bunch of other stuff
    modelBuilder.Entity<Contact>().ToTable("contacts");
    modelBuilder.Entity<Contact>().HasKey(b => b.nCont_id);
    modelBuilder.Entity<Contact>().HasOptional(b => b.WebsiteMembership).WithRequired(b => b.Contact).Map(b => b.MapKey("WebsiteMembershipId"));

    modelBuilder.Entity<WebsiteMembership>().ToTable("WebsiteMembership");
    modelBuilder.Entity<WebsiteMembership>().HasKey(b => b.WebsiteMembershipId);

}

But I get an exception when I try doing:

var websiteMembership = context.WebsiteMemberships.Where(c => c.WebsiteMembershipId == 1645942).FirstOrDefault();

Exception:

Schema specified is not valid. Errors: (263,6) : error 0019: Each property name in a type must be unique. Property name 'WebsiteMembershipId' was already defined.

Does this mean I can't set the same primary key as a foreign key on EF CodeFirst? Or I'm doing something wrong here? Would it work if the primary key wasn't the same column as the foreign key?

Advice is very much appreciated!

解决方案

I think when you define this mapping...

modelBuilder.Entity<Contact>()
    .HasOptional(b => b.WebsiteMembership)
    .WithRequired(b => b.Contact)
    .Map(b => b.MapKey("WebsiteMembershipId"));

...you implicitely define what's the principal and what's the dependent of the relationship. Obviously Contact is the principal because having the WebsiteMembership property set is optional for the Contact, it can be stored without the WebsiteMembership. The WebsiteMembership entity on the other side has a required reference to a Contact which means it depends on the Contact.

The principal (Contact) is the entity with the primary key, the dependent (WebsiteMembership) the entity with the foreign key. So, when you use MapKey to set the name WebsiteMembershipId of the foreign key column you define a column for the table WebsiteMembership, not for Contact. But WebsiteMembership already has a property called WebsiteMembershipId. (I believe that's the point where EF complains that a "Property name 'WebsiteMembershipId' was already defined.) In a one-to-many relationship the foreign key would be the ContactId as a separate property/column and you would have to use HasForeignKey instead of MapKey. But in a one-to-one relationship it is clear that the foreign key is the primary key at the same time, so you don't need to define the foreign key at all.

To cut a long story short: Just remove MapKey:

modelBuilder.Entity<Contact>()
    .HasOptional(b => b.WebsiteMembership)
    .WithRequired(b => b.Contact);

(But now I am curious if you can define a relationship between an int and a decimal property or if you get the next error.)

这篇关于EF 4.1 Code First - 使用非标准列名映射一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆