Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架5.0复合外键到非主键-可能吗?_C#_.net_Entity Framework 5_Poco - Fatal编程技术网

C# 实体框架5.0复合外键到非主键-可能吗?

C# 实体框架5.0复合外键到非主键-可能吗?,c#,.net,entity-framework-5,poco,C#,.net,Entity Framework 5,Poco,我在.net 4.5控制台应用程序中使用Entity Framework 5.0.0.0,我必须访问包含两个表的数据库,其中两个表之间存在外键关系,如下所示: 奇怪的是,外键位于B(Almost1,Almost2)和A(Almost1,Almost2)之间,而不是从B(AId)到A(AId)。SQL server允许这样做,因为Almost1和Almost2的组合是唯一的,并且两者都不可为空(至少在表A上-在B上,它们是可选关系,但这是由by决定的) 下面是一些创建这种情况的SQL: CREA

我在.net 4.5控制台应用程序中使用Entity Framework 5.0.0.0,我必须访问包含两个表的数据库,其中两个表之间存在外键关系,如下所示:

奇怪的是,外键位于
B(Almost1,Almost2)
A(Almost1,Almost2)
之间,而不是从
B(AId)
A(AId)
。SQL server允许这样做,因为
Almost1
Almost2
的组合是唯一的,并且两者都不可为空(至少在表
A
上-在
B
上,它们是可选关系,但这是由by决定的)

下面是一些创建这种情况的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])
问题是,实体框架似乎不允许这样做——是这样还是我没有正确定义模型

这是我的简历:

它可以工作,但我并不真的想这样做,因为还有一个表(我们称之为
C
)以传统方式与
a
相关,它有一个
AId
列,外键从
C.AId
转到
a.AId


是的,我知道这有点奇怪-但有可能在实体框架中处理这个问题吗?

如前所述,因为EF不支持唯一键和其他SQL对象。我最终创建了一些脚本作为嵌入式资源,并让它们作为drop/create初始值设定项的种子过程的一部分执行


不确定这是否允许您在代码中的对象之间导航,但在一个过程中更新数据库效果很好。

Entity Framework不支持唯一键,不幸的是,如果没有唯一键,它就无法为您的外键建模。
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();
        }
    }
}
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"));
}