我有以下实体类:
using System;
using System.Collections.Generic;
using Facebook.Business.Domain.Accounts;
namespace Business.Domain.Posts
{
/// <summary>
/// This class defines a post.
/// </summary>
public class Post : Entity<Post>
{
#region Fields
private UserAccount _author;
private UserAccount _owner;
private DateTime _date;
private string _text;
private IList<Comment> _comments;
#endregion
#region Ctors
protected Post()
{
}
public Post(UserAccount author,
UserAccount owner,
DateTime date,
string text)
{
_author = author;
_owner = owner;
_date = date;
_text = text;
_comments = new List<Comment>();
}
#endregion
/// <summary>
/// Gets or sets the account that writes and sends the current post.
/// </summary>
public virtual UserAccount Author
{
get { return _author; }
protected set { _author = value; }
}
/// <summary>
/// Gets or sets the datetime of the current post.
/// </summary>
public virtual DateTime Date
{
get { return _date; }
protected set { _date = value; }
}
/// <summary>
/// Gets or sets the text of the current post.
/// </summary>
public virtual string Text
{
get { return _text; }
protected set { _text = value; }
}
/// <summary>
/// Gets or sets the user that receives the current post.
/// </summary>
public virtual UserAccount Owner
{
get { return _owner; }
protected set { _owner = value; }
}
/// <summary>
/// Gets or sets the comments for the current post.
/// </summary>
public virtual IList<Comment> Comments
{
get { return _comments; }
protected set { _comments = value; }
}
public void Add(Comment comment)
{
_comments.Add(comment);
}
#region Implementation of ICommentable
IEnumerable<Comment> ICommentable.Comments { get { return Comments; } }
#endregion
}
}
类UserAccount对Post类一无所知,UserAccount也是一个实体。
然后我需要在相应的存储库类中实现此方法:
/// <summary>
/// Retrieve the posts that were posted by a given account: <paramrefname="author"/>
/// </summary>
/// <param name="author">An account.</param>
/// <returns>The posts that were posted by <paramref name="author"/></returns>
public IQueryable<Post> FindPostsFrom(UserAccount author)
{
ContractUtil.NotNull(author);
return Set.Where(post => post.Author.Equals(author));
}
但是当我运行测试时,我得到以下错误:
System.NotSupportedException:无法创建常量值 输入'Facebook.Business.Domain.Accounts.UserAccount'。只有原始 在此上下文中支持类型或枚举类型。
......和堆栈......
在 System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter父,常量表达式LINQ) 在 System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式LINQ) 在 System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter父,BinaryExpression LINQ) 在 System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式LINQ) 在 System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression拉姆达,DbExpression输入) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter父,MethodCallExpression呼叫,参考DbExpression源,参考DbExpressionBinding sourceBinding,参考DbExpression拉姆达) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter父,MethodCallExpression调用) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter父,MethodCallExpression LINQ) 在 System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式LINQ) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter父,MethodCallExpression调用) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter父,MethodCallExpression LINQ) 在System.Data.Objects.ELinq.ExpressionConverter.Convert()at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(可空
1 forMergeOption) at System.Data.Objects.ObjectQuery
1.GetResults(可空1 forMergeOption) at System.Data.Objects.ObjectQuery
1.System.Collections.Generic.IEnumerable.GetEnumerator() 在System.Linq.Enumerable.First(IEnumerable1 source) at System.Linq.Queryable.First(IQueryable
1 source)at Data.EntityFramework.Tests.PostRepositoryTests.FindPostsFrom_FindingAPostGivenAnAuthor_ShouldRetrieveIt() 在PostRepositoryTests.cs中:第136行
到目前为止,有人能解释一下这里发生了什么吗? 似乎我不应该使用导航属性进行查询。
任何人都可以给我一个替代解决方案吗?
提前致谢。
答案 0 :(得分:1)
由于他们是相关实体,并且这种关系是一对多(一位作者有很多帖子),这意味着每个帖子都有一个保留authorId值的字段。
您可以重写查询以搜索post.authorId = author.Id。
的帖子答案 1 :(得分:1)
在Entity Framework中,查询应始终在谓词中使用原始属性。所以你可以做到
Set.Where(post => post.Author.Id == author.Id);
或(如dutzu建议的那样)将AuthorId
公开为Post
的属性。如果你这样做,你必须告诉EF AuthorId
和Author
都是同一个外键的一部分。这取决于您使用的API(ObjectContext或DbContext)如何做到这一点。
EF如此严格(可能更多)的一个原因是它不能对值类型或类的相等性做出任何假设。由于EF允许使用POCO,Equals()
或==
运算符不会自动评估键值的相等性。 POCO必须明确实施IEquatable
以确保按键平等。另一方面,原始值的平等总是被定义。