Dot-Net

EF4.1 Code First 複雜類型作為主鍵

  • June 13, 2017

我目前正在嘗試使用 Entity Framework 4.1 的 RC 及其程式碼優先方法為我的域對象實現儲存庫。現在我有一個域實體“Voyage”,它有一個封裝在“VoyageNumber”類型中的唯一標識符

public class VoyageNumber
{
   private readonly string number;

   public VoyageNumber(string number)
   {
       Validate.NotNull(number, "VoyageNumber is required");

       this.number = number;
   }

   public string Id
   {
       get { return number; }
   }

現在,當我在 DbContext 的配置中執行此操作時出現異常:

modelBuilder.Entity<Voyage>().HasKey<VoyageNumber>(k => k.VoyageNumber);

屬性“VoyageNumber”不能用作實體“Domain.Model.Voyages.Voyage”的鍵屬性,因為該屬性類型不是有效的鍵類型。只有標量類型,字元串和字節

$$ $$是支持的鍵類型。

當我嘗試這個時:

modelBuilder.Entity<Voyage>().HasKey<string>(k => k.VoyageNumber.Id);

屬性表達式“k => k.VoyageNumber.Id”無效。該表達式應表示一個屬性:C#: ’t => t.MyProperty'

我真的必須丟棄我的 VoyageNumber 並用原始類型替換它嗎?

這是限制。關鍵成員只能是實體中直接的標量屬性。複雜類型表示為不支持的複雜屬性。

我們可以通過以下方式解決。希望它有幫助。

public class TestPaperResultId: ValueObject
{
   public TestPaperResultId(string testPaperId, string userId)
   {
       TestPaperId = testPaperId;
       UserId = userId;
   }

   protected TestPaperResultId() { }

   public string TestPaperId { get; protected set; }
   public string UserId { get; protected set; }

   public override string ToString()
   {
       return $"{TestPaperId}_{UserId}";
   }
}

public class TestPaperResult : AggregateRoot
{
   private TestPaperResultId _id;

   public TestPaperResultId Id
   {
       get => _id ?? (_id = new TestPaperResultId(TestPaperId, UserId));
       protected set
       {
           TestPaperId = value.TestPaperId;
           UserId = value.UserId;
           _id = value;
       }
   }

   public string TestPaperId { get; protected set; }

   public string UserId { get; protected set; }

   protected TestPaperResult() { }

   public TestPaperResult(TestPaperResultId id,
                          decimal fullmarks)
   {
       Id = id;
       Fullmarks = fullmarks;
   }
}

在 dbContext 中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);

   modelBuilder.Entity<TestPaperResult>()
               .Ignore(t => t.Id)
               .HasKey(t => new {t.TestPaperId, t.UserId});
}

在儲存庫中:

public Task<TestPaperResult> FindTestPaperResultAsync(TestPaperResultId id)
{
    return GetByKeyAsync<TestPaperResult>(id.TestPaperId, id.UserId);
}

引用自:https://stackoverflow.com/questions/5522584