我目前正在尝试使用实体框架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'因为 属性类型不是有效键 类型。只有标量类型,字符串和 byte []是受支持的密钥类型。
当我尝试这个时:
modelBuilder.Entity<Voyage>().HasKey<string>(k => k.VoyageNumber.Id);
属性表达式'k =&gt; k.VoyageNumber.Id'无效。该 表达应该代表一个 property:C#:'t =&gt; t.MyProperty'
我是否真的要废弃我的VoyageNumber并用原始类型替换它?
答案 0 :(得分:14)
这是限制。关键成员可以只是实体中的标量属性。复杂类型表示为不支持的复杂属性。
答案 1 :(得分:0)
对于隔离类,您可以通过向执行SqlQuery<>
的DbContext添加“get”方法来执行只读变通方法,并在内部将表映射到类(以老式方式)。 / p>
我在这里编写了一个最小的测试用例:https://github.com/timabell/ef-complex-pk
e.g。
public class TestDbContext : DbContext
{
public IEnumerable<UberWidget> GetUberWidgets()
{
return Database.SqlQuery<WidgetSqlDto>("select WidgetId, Name from Widgets")
.Select(dto => new UberWidget
{
UberWidgetId = new IdWrap { IdWrapId = dto.WidgetId },
Name = dto.Name
});
}
}
答案 2 :(得分:0)
我们可以用以下解决方法。希望它有用。
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);
}