EF代码优先:重复的外键(一个来自名称约定,一个来自导航属性) [英] EF Code First: Duplicate foreign keys (one from name convention, one from navigation property)

查看:82
本文介绍了EF代码优先:重复的外键(一个来自名称约定,一个来自导航属性)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试使用EF Code First创建一个SQL数据库。

I'm trying to create an SQL database by using EF Code First.

假设我有以下代码:

public class Account
{
    public int Id;
    public ICollection<User> Users;
}

public class User
{
    public int Id;
    public int AccountId;
}

public class AccountContext : DbContext
{
    public DbSet<Account> Accounts;
    public DbSet<User> Users;
}

(请注意,缺少任何Fluent API命令或数据注释;我想

(Note the lack of any Fluent API commands or Data Annotations; I want to do this by convention.)

创建数据库后,我在Users表中获得以下字段:

When the database is created, I get the following fields in the Users table:

Id
AccountId
Account_Id

为什么EF不能理解 AccountId是指Account的 Id主键这一事实?我希望避免在可能的情况下使用Fluent API / DA手动进行映射,并且希望避免在用户上拥有帐户导航属性。

Why isn't EF picking up on the fact that "AccountId" refers to the "Id" primary key (by convention) of Account? I want to avoid mapping this manually with Fluent API/DA if possible, and I want to avoid having the Account navigation property on User.

推荐答案

通过数据注释(非常快速)或流利的映射,我只有两种方法可以知道如何执行您要执行的操作。您不能只说 public int AccountId; 并期望一切正常。

There are only two ways i know how to perform what you are looking to do, either by Data Annotation (Very quick) or Fluent Mapping. You can't just say public int AccountId; and expect everything to work.

Fluent API映射双向

public class Account
{
   public int Id { get; set; }

   public ICollection<User> Users { get; set; }
}

public class User
{
   public int Id { get; set; }

   public Account Account { get; set; }
}

public class AccountContext : DbContext
{
   public AccountContext()
        : base("DefaultConnection")
    {

    }

   public DbSet<Account> Accounts { get; set; }
   public DbSet<User> Users { get; set; }

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasRequired(u => u.Account) 
            .WithMany(a => a.Users) 
            .HasForeignKey(u => u.AccountId);
    }
}

双向数据注释

public class Account
{
   [Key]
   public int Id { get; set; }

   public ICollection<User> Users { get; set; }
}

public class User
{
   [Key]
   public int Id { get; set; }

   [ForeignKey("Account"), DatabaseGenerated(DatabaseGeneratedOption.None)]
   public int AccountId { get; set; }

   public Account Account { get; set; }
}

// and of course you need your context class, but with less code

public class AccountContext : DbContext
{
   public AccountContext()
        : base("DefaultConnection")
    {

    }

   public DbSet<Account> Accounts { get; set; }

   public DbSet<User> Users { get; set; }       
}

没有双向数据注释或Fluent API映射

public class Account
{
   public int Id { get; set; } //as Id in Accounts Table

   public ICollection<User> Users { get; set; }
}

public class User
{
   public int Id { get; set; } //as Id in Users Table

   public Account Account { get; set; } // as Account_Id in Users Table
}

// and of course you need your context class, but with less code

public class AccountContext : DbContext
{
   public AccountContext()
        : base("DefaultConnection")
    {

    }

   public DbSet<Account> Accounts { get; set; }

   public DbSet<User> Users { get; set; }       
}

我希望这可以帮助您或其他有疑问的人

I hope this helps you or anyone else in doubt

编辑

如果要避免使用双向导航,然后像这样更改个用户

If you want to avoid Bi-Directional navigation then make changes to Users like this

public class User
{
   public int Id { get; set; }

   //delete below from User class to avoid Bi-directional navigation 
   //public Account Account { get; set; }
}

注意:未经测试,但逻辑是声音

Note: Not tested but the logic is sound

这篇关于EF代码优先:重复的外键(一个来自名称约定,一个来自导航属性)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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