I know the question already has a solution (eg. this question) but I really can’t afford to attach the mapping logic in the same assembly where the domain (POCO classes) is.
Is there any other way?
I found this nice blog post but I couldn’t get it working.
Here is the model:
public class Institute
{
/**
Code omitted
**/
protected virtual ICollection<InstituteText> InnerInstituteTexts { get; set; }
private InstituteTextSet _TextSets;
public InstituteTextSet Texts
{
get
{
if (_TextSets == null)
_TextSets = new InstituteTextSet(InnerInstituteTexts);
return _TextSets;
}
}
}
Mapping code:
var instituteTextExpression = ObjectAccessor<Institute>.CreateExpression<ICollection<InstituteText>>("InnerInstituteTexts");
institute.HasMany(instituteTextExpression)
.WithRequired()
.HasForeignKey(t => t.InstituteId);
where CreateExpression is defined as:
public static Expression<Func<T, TResult>> CreateExpression<TResult>(string propertyOrFieldName)
{
ParameterExpression param = Expression.Parameter(typeof(T), "propertyOrFieldContainer");
Expression body = Expression.PropertyOrField(param, propertyOrFieldName);
LambdaExpression lambda = Expression.Lambda(typeof(Func<T, TResult>), body, param);
return (Expression<Func<T, TResult>>) lambda;
}
the error I get is:
Initialization method
Studentum.Core.Tests.InstituteTests.Initialize
threw exception.
System.TypeInitializationException:
System.TypeInitializationException:
The type initializer for
‘Studentum.Core.FluentCoreRepositoryFactory’
threw an exception. —>
System.InvalidOperationException: The
configured property
‘InnerInstituteTexts’ is not a
declared property on the entity
‘Institute’. Verify that it has not
been explicitly excluded from the
model and that it is a valid primitive
property..
The first thing that came to mind is the
InternalsVisibleToassembly attribute. This allows you to name “friend” assemblies that also have access to internal members. I wasn’t sure if this would work with EF CodeFirst, but I tried it and it appears to work just fine. You would have to change your model assembly slightly, but I think it is a reasonable change.You would first need to change your property declaration to protected internal:
Then, in your model assembly, add the
InternalsVisibleToassembly attribute in your AssemblyInfo.cs file with the name of your mapping assembly.Finally, you can define your mapping of the property in the mapping assembly like any other publicly accessible property.