I’m using EF code first to define two relations on a complex type with an unsuccessful result of an InvalidOperation Exception “{“The expression ‘p => p.AuditInfo.CreatedBy’ is not a valid property expression. The expression should represent a property: C#: ‘t => t.MyProperty’ VB.Net: ‘Function(t) t.MyProperty’.”}”
What i’m doing wrong ?
Relevant code:
public class AuditInfo
{
public DateTime? CreatedOn { get; internal set; }
public Guid? CreatedById { get; internal set; }
public User CreatedBy { get; internal set; }
public DateTime? ModifiedOn { get; internal set; }
public Guid? ModifiedById { get; internal set; }
public User ModifiedBy { get; internal set; }
public byte[] ModifiedTimestamp;
}
public class User
{
public Guid Id { get; internal set; }
public string Email { get; internal set; }
public AuditInfo AuditInfo { get; internal set; }
}
class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
this.HasOptional(p => p.AuditInfo.CreatedBy).WithMany().HasForeignKey(p => p.AuditInfo.CreatedById);
this.HasOptional(p => p.AuditInfo.ModifiedBy).WithMany().HasForeignKey(p => p.AuditInfo.ModifiedById);
}
}
public class Test3DbContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<AuditInfo>();
modelBuilder.Configurations.Add(new UserMap());
}
}
Database Table:
User { Id, Email, …, CreatedById, ModifiedById, CreatedOn, ModifiedOn, … }
A complex type is treated like a value object and is appended to the end of the table that is being created. So, User will have columns Id, then email, then the AuditInfo columns. The only separation is within the code, not in the database. Therefore, complex types are tracked by their parent class, and have no foreign keys. You will need to rethink your design if you are looking for something else.
UPDATED:
If what you are looking for is just to make sure that CreatedBy/ModifiedBy is mapped for foreign key constraints, then it appears this is not possible using a ComplexType. You would have to put the full audit info in the user table. This is specified in the Complex Type documentation