我知道这个问题已经有了一个解决方案(例如this question)但是我真的无法将映射逻辑附加到域(POCO类)所在的同一个程序集中。
还有其他办法吗?
我找到了这个nice blog post,但我无法让它发挥作用。 这是模型:
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;
}
}
}
映射代码:
var instituteTextExpression = ObjectAccessor<Institute>.CreateExpression<ICollection<InstituteText>>("InnerInstituteTexts");
institute.HasMany(instituteTextExpression)
.WithRequired()
.HasForeignKey(t => t.InstituteId);
其中CreateExpression定义为:
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;
}
我得到的错误是:
初始化方法 Studentum.Core.Tests.InstituteTests.Initialize 扔了例外。 System.TypeInitializationException: System.TypeInitializationException: 类型初始值设定项 'Studentum.Core.FluentCoreRepositoryFactory' 抛出一个例外。 ---&GT; System.InvalidOperationException:The 配置属性 'InnerInstituteTexts'不是 在实体上声明的财产 '研究所'。确认它没有 被明确排除在外 模型,它是一个有效的原语 属性..
答案 0 :(得分:8)
首先想到的是InternalsVisibleTo
程序集属性。这允许您命名也可以访问内部成员的“朋友”程序集。我不确定这是否适用于EF CodeFirst,但我尝试过它似乎工作得很好。您必须稍微更改模型组件,但我认为这是一个合理的更改。
您首先需要将您的财产声明更改为受保护的内部:
protected internal virtual ICollection<InstituteText> InnerInstituteTexts { get; set; }
然后,在模型程序集中,使用映射程序集的名称在AssemblyInfo.cs文件中添加InternalsVisibleTo
程序集属性。
[assembly: InternalsVisibleTo("MappingAssemblyName")]
最后,您可以像在任何其他可公开访问的属性中一样,在映射程序集中定义属性的映射。
institute.HasMany(i => i.InnerInstituteTexts)
.WithRequired()
.HasForeignKey(t => t.InstituteId);