我在.NET 4.5的控制檯應用程序使用實體框架5.0.0.0和我有它兩個表來訪問數據庫,象這樣它們之間的外鍵關係:實體框架5.0複合外鍵非主鍵 - 是否有可能?
奇數關於它的一點是,外鍵在B(Almost1, Almost2)
和A(Almost1, Almost2)
之間,而不是從B(AId)
到A(AId)
。這是由SQL服務器允許的,因爲Almost1
和Almost2
組合是唯一的,都不可爲空(至少在表A
上 - 它們是B
它們是因爲它是可選關係,但是是由)。
下面是一些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#:
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();
}
}
}
它拋出一個InvalidOperationException
說:
指定的關聯外鍵列 'Almost1,差不多有' 無效。指定的列數必須與主鍵列的數量匹配。
如果我忽略了AId
列,而是讓Almost1
和Almost2
複合主鍵,所以我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"));
}
它的工作原理,但我真的不希望這樣做,因爲還有一個表(我們稱之爲C
),它與A
以傳統方式相關,具有AId
列和外鍵從C.AId
到A.AId
。
是的,這有點奇怪我知道 - 但是有可能在Entity Framework中處理這個問題嗎?
實體框架不支持唯一鍵,如果沒有這些鍵,不幸的是它不能建模您的外鍵。 – hvd
@hvd :-(好的,謝謝 – kmp