I\'m currently trying to implement the repositories for my domain objects with the RC of Entity Framework 4.1 and its code first approach. Now I have a domain entity \"Voyag
This is the limitation. Key members can be only scalar properties directly in the entity. Complex type is represented as complex property which is not supported.
We can resolve it with the below. Hope it's helpful.
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;
}
}
in dbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TestPaperResult>()
.Ignore(t => t.Id)
.HasKey(t => new {t.TestPaperId, t.UserId});
}
in Repository:
public Task<TestPaperResult> FindTestPaperResultAsync(TestPaperResultId id)
{
return GetByKeyAsync<TestPaperResult>(id.TestPaperId, id.UserId);
}
For an isolated class you could do a read-only workaround by adding a "get" method to your DbContext that does a SqlQuery<>
and maps the table to the class internally (the old-fashioned way).
I've worked up a minimal test-case here: 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
});
}
}