EntityFramework命名我的映射表错误

时间:2014-06-25 01:36:54

标签: entity-framework entity-framework-5

我有以下实体类定义:

[Table("Users")]
public class WebUser
{
    public virtual int Id { get; set; }

    public virtual ICollection<Client> Clients { get; set; }

    // more properties...
}

请注意,表名与类名不同。我还有一个ClientUsers表,它是客户端和用户的多对多映射。问题是,当我尝试访问webUser.Clients属性时,我得到以下异常:

"Invalid object name 'dbo.ClientWebUsers'."

看起来Entity Framework正在尝试猜测第三个表的名称,但它显然不够聪明,不能考虑我在那里的表属性。如何告诉EF它是ClientUsers而不是ClientWebUsers?还有什么规则可以知道哪个表名首先出现,哪个表名在新表名中排在第二位?我认为这不是按字母顺序排列的。

我使用的是EF 5.0。谢谢!

2 个答案:

答案 0 :(得分:4)

从您使用Code First的内容来看,我会相应地回答。如果这不正确,请告诉我。

我相信用于确定多对多表的名称的约定由它们在SomeContext:DbContext类中作为DbSet属性出现的顺序决定。

至于强制EntityFramework为您的表命名,您可以在SomeContext:DbContext类的OnModelCreating方法中使用Fluent API,如下所示:

public class DatabaseContext : DbContext
{
    public DatabaseContext()
        : base("SomeDB")
    {
    }

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

    public DbSet<Client> Clients { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<WebUser>().HasMany(c => c.Clients)
            .WithMany(p => p.WebUsers).Map(
            m =>
            {
                m.MapLeftKey("ClientId");
                m.MapRightKey("UserId");
                m.ToTable("ClientUsers");
            });
    }
}

这假定您的课程类似于以下内容:

[Table("Users")]
public class WebUser
{
    public virtual int Id { get; set; }

    public virtual ICollection<Client> Clients { get; set; }

    // more properties...
}

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

    public ICollection<WebUser> WebUsers { get; set; }

    // more properties
}

最后,这是一个集成测试(NUnit),展示了正常运行的功能。您可能需要在运行之前删除数据库,因为Code First应该更新/迁移/重新创建它。

[TestFixture]
public class Test
{
    [Test]
    public void UseDB()
    {
        var db = new DatabaseContext();

        db.Users.Add(new WebUser { Clients = new List<Client> { new Client() } });
        db.SaveChanges();

        var webUser = db.Users.First();
        var client = webUser.Clients.FirstOrDefault();

        Assert.NotNull(client);
    }
}

修改 Link到Fluent API的相关文档

答案 1 :(得分:0)

Rowan的answer(在此处添加以供参考):

以下是有关如何配置多对多表(包括指定表名)的信息。您所追求的代码如下:

modelBuilder.Entity<WebUser>()
    .HasMany(u => u.Clients)
    .WithMany(c => c.WebUsers)
    .Map(m => m.ToTable("ClientUsers");

〜罗文