简体   繁体   English

Entity Framework 5.0非主键的复合外键-可能吗?

[英]Entity Framework 5.0 composite foreign key to non primary key - is it possible?

I am using Entity Framework 5.0.0.0 in a .net 4.5 console application and I have to access a database with two tables in it with a foreign key relationship between them like so: 我在.net 4.5控制台应用程序中使用Entity Framework 5.0.0.0,并且必须访问其中有两个表且它们之间具有外键关系的数据库,如下所示:

概观

The odd thing about it is that the foreign key is between B(Almost1, Almost2) and A(Almost1, Almost2) not from B(AId) to A(AId) . 奇怪的是,外键不在B(AId)A(AId)之间B(Almost1, Almost2)而在B(Almost1, Almost2)A(Almost1, Almost2) A(AId) This is allowed by SQL server as Almost1 and Almost2 combined are unique and neither are nullable (on table A at least - on B they are as it is an optional relationship but that is by the by). SQL Server允许这样做,因为Almost1Almost2组合是唯一的,并且都不是可以为null的(至少在表A上-在B它们是可选关系,但是通过by)。

Here's some SQL for creating this situation: 这是用于创建这种情况的一些SQL:

CREATE TABLE [dbo].[A](
    [AId] [int] IDENTITY(1,1) NOT NULL,
    [Almost1] [int] NOT NULL,
    [Almost2] [int] NOT NULL,
 CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED 
(
    [AId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [A_Constraint] UNIQUE NONCLUSTERED 
(
    [Almost1] ASC,
    [Almost2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[B](
    [BId] [int] IDENTITY(1,1) NOT NULL,
    [Almost1] [int] NULL,
    [Almost2] [int] NULL,
 CONSTRAINT [PK_B] PRIMARY KEY CLUSTERED 
(
    [BId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

ALTER TABLE [dbo].[B] ADD  CONSTRAINT [FK_A_B] FOREIGN KEY([Almost1], [Almost2])
REFERENCES [dbo].[A] ([Almost1], [Almost2])

The thing is, it seems that it is not allowed by Entity Framework - is this the case or am I just not defining my model correctly? 事实是,Entity Framework似乎不允许这样做-是这种情况还是我只是未正确定义模型?

Here is my c#: 这是我的C#:

public class MyContext : DbContext
{
    public MyContext(string connectionString) : base(connectionString)
    {
        MyAs = Set<A>();
        MyBs = Set<B>();
    }

    public DbSet<A> MyAs { get; private set; }
    public DbSet<B> MyBs { get; private set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var aEntity = modelBuilder.Entity<A>();
        aEntity.ToTable("A");
        aEntity.HasKey(a => a.AId);

        var bEntity = modelBuilder.Entity<B>();
        bEntity.ToTable("B");
        bEntity.HasKey(a => a.BId);
        bEntity
            .HasOptional(b => b.A)
            .WithMany(a => a.Bs)
            .Map(m => m.MapKey("Almost1", "Almost2"));
    }
}

public class A
{
    public int AId { get; set; }
    public int Almost1 { get; set; }
    public int Almost2 { get; set; }
    public virtual ICollection<B> Bs { get; private set; }
    public void AddB(B b)
    {
        if (b == null) throw new ArgumentNullException("b");
        if (Bs == null) Bs = new List<B>();
        if (!Bs.Contains(b)) Bs.Add(b);
        b.A = this;
    }
}

public class B
{
    public int BId { get; set; }
    public virtual A A { get; set; }
}

class Program
{
    static void Main()
    {
        using (var ctx = new MyContext(@"connection string"))
        {
            ctx.MyAs.Add(new A { Almost1 = 1, Almost2 = 1 });
            ctx.SaveChanges();
        }
    }
}

It throws an InvalidOperationException saying: 它抛出一个InvalidOperationException

The specified association foreign key columns 'Almost1, Almost2' are invalid. 指定的关联外键列'Almost1,Almost2'无效。 The number of columns specified must match the number of primary key columns. 指定的列数必须与主键列数匹配。

If I ignore the AId column and instead make Almost1 and Almost2 a composite primary key, so my OnModelCreating method now looks like this: 如果我忽略AId列,而是使Almost1Almost2成为复合主键,那么我的OnModelCreating方法现在看起来像这样:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    var aEntity = modelBuilder.Entity<A>();
    aEntity.ToTable("A");
    aEntity.HasKey(a => new { a.Almost1, a.Almost2 });
    aEntity.Ignore(a => a.AId);

    var bEntity = modelBuilder.Entity<B>();
    bEntity.ToTable("B");
    bEntity.HasKey(a => a.BId);
    bEntity
        .HasOptional(b => b.A)
        .WithMany(a => a.Bs)
        .Map(m => m.MapKey("Almost1", "Almost2"));
}

It works, but I don't really want to do this as there is also a table (let's call it C ) that relates to A in the traditional way by having an AId column and the foreign key is going from C.AId to A.AId . 它可以工作,但是我并不是真的想要这样做,因为还有一个表(我们称它为C ),该表通过使用AId列以传统方式与A ,并且外键从C.AIdA.AId

Yeah, it's a bit weird I know - but is it possible to deal with this in Entity Framework? 是的,我知道这有点奇怪-但是可以在Entity Framework中处理吗?

As mentioned, since EF doesn't support unique keys and other SQL objects. 如前所述,由于EF不支持唯一键和其他SQL对象。 I ended up creating some scripts as embedded resources and have them execute as part of the seed process of the drop/create initializer. 我最终创建了一些脚本作为嵌入式资源,并让它们作为放置/创建初始化程序的种子过程的一部分执行。

Not sure if this will allow you to navigate between the objects in code, but it works pretty nicely to have the database get updated in one process. 不知道这是否允许您在代码中的对象之间导航,但是在一个过程中更新数据库非常好用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架-具有主键和复合外键的多对多 - Entity Framework - many to many with primary key and composite foreign key 实体框架-由3个外键组成的复合主键 - Entity Framework - Composite Primary Key formed by 3 Foreign Keys Entity Framework Core - 复合键和外键作为主键 - Entity Framework Core - Composite and Foreign Keys as Primary Key 实体框架6.1.3将外键映射到非主键 - Entity Framework 6.1.3 Mapping Foreign key to non primary key 实体框架代码优先 - 非主键字段的外键 - Entity Framework Code First - Foreign Key to non primary key field 实体框架:外键作为组合键的一部分 - Entity Framework:Foreign Key as part of Composite key Entity Framework Core:使用自动生成的外键作为复合主键的一部分 - Entity Framework Core: use auto-generated foreign key as part of composite primary key 如何在 C# 的外键中使用 Entity Framework 的复合主键 - How to use a composite primary key with Entity Framework from a foreign key in C# 如何在Entity Framework中为复合主键的特定列创建外键模型 - How to make foreign key inside models for particular column of composite primary key in Entity Framework 在Code-First Entity Framework中包含复合主键中的外键 - Include foreign key in composite primary key in Code-First Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM