C# 如何传递对象';在构建Linq2Sql查询时,是否将属性(而不是对象)转换为表达式?

C# 如何传递对象';在构建Linq2Sql查询时,是否将属性(而不是对象)转换为表达式?,c#,.net,linq,linq-to-sql,expression,C#,.net,Linq,Linq To Sql,Expression,tl;dr:我正在寻找一种方法,在构建Linq2Sql查询时,将对象的属性image.Member(而不是对象image)传递到表达式中。这样,我将使用Expression而不是Expression 以下是我的域模型(如果有必要,请参阅EF 5): 接下来,我想使用以下逻辑从数据库中获取所有图像: 如果用户已登录,则拍摄其所有图像和所有其他图像 可搜索的成员。如果用户未登录,只需 所有其他成员的所有图像都是可搜索的 在LINQ2对象中,这将如下所示: var images = imagesRe

tl;dr:我正在寻找一种方法,在构建Linq2Sql查询时,将对象的属性
image.Member
(而不是对象
image
)传递到表达式中。这样,我将使用
Expression
而不是
Expression


以下是我的域模型(如果有必要,请参阅EF 5):

接下来,我想使用以下逻辑从数据库中获取所有图像:

如果用户已登录,则拍摄其所有图像和所有其他图像
可搜索的成员
。如果用户未登录,只需 所有其他
成员的所有图像都是可搜索的

在LINQ2对象中,这将如下所示:

var images = imagesRepository.All().ToList().AsIEnumerable();

if (this.User == null)
{
    images = images.Where(x => x.Member.IsSearchable == true);
}
else
{
    var currentMemberId = this.User.Id;
    images = images.Where(x => x.Member.IsSearchable == true || x.Member.Id == currentMemberId);
}
当然,这是低效的-我不想从DB加载10000个图像,只是为了得到10个。这让我想到了Linq2Sql。注意:我知道我可以将逻辑从'IsSearchable'复制到'Where'子句中,我将得到适当的'IQueryable',但我有两个问题:

  • isearcable
    以后很容易更改逻辑-我永远也记不起这次复制/粘贴了
  • 我将不得不复制它两次(因为currentMemberId处于或状态)-这将使代码难以读取
  • 这让我相信,我唯一的解决办法就是使用表达。我们开始了(感谢):

    并将其替换为
    Member
    ,并在创建查询时告诉表达式使用“Image”对象中的“Member”:

    Expression<Func<Member, bool>> memberIsSearchable = 
        m => m.IsPrivate == false && 
             string.IsNullOrEmpty(m.AboutMe) == false && 
             string.IsNullOrEmpty(m.ScreenName) == false;
    
    images = images.Where(x => memberIsSearchable(x.Member));  // pseudocode
    
    表达式成员可搜索=
    m=>m.IsPrivate==false&&
    string.IsNullOrEmpty(m.AboutMe)=false&&
    string.IsNullOrEmpty(m.ScreenName)==false;
    images=images.Where(x=>memberissearable(x.Member));//伪码
    

    这样做的原因是使
    成员可搜索
    表达式通用化,并在项目的其他部分使用它。

    我花了一段时间才弄清楚您的问题到底是什么-我想,我现在明白了

    尝试从成员开始(而不是从图像开始)。也许您需要引入其他导航属性:

    Expression<Func<Member, bool>> IsSearchable =  member => !member.IsPrivate
            && !String.IsNullOrEmpty(member.AboutMe)
            && !String.IsNullOrEmpty(member.ScreenName);
    
    Member currentUser = null;
    using (var container = new /**/())
    {
        var images = container.Members.Where(IsSearchable).SelectMany(member => member.Images);
        if (currentUser != null)
            images = images.Concat(currentUser.Images);
    
        var result = images.ToArray();
    }
    
    表达式IsSearchable=member=>!私人会员
    && !String.IsNullOrEmpty(member.AboutMe)
    && !String.IsNullOrEmpty(member.ScreenName);
    成员currentUser=null;
    使用(var container=new/**/())
    {
    var images=container.Members.Where(可搜索)。选择many(member=>member.images);
    如果(currentUser!=null)
    images=images.Concat(currentUser.images);
    var result=images.ToArray();
    }
    
    Expression<Func<Image, bool>> memberIsSearchable = ...
    
    Expression<Func<Member, bool>> memberIsSearchable = 
        m => m.IsPrivate == false && 
             string.IsNullOrEmpty(m.AboutMe) == false && 
             string.IsNullOrEmpty(m.ScreenName) == false;
    
    images = images.Where(x => memberIsSearchable(x.Member));  // pseudocode
    
    Expression<Func<Member, bool>> IsSearchable =  member => !member.IsPrivate
            && !String.IsNullOrEmpty(member.AboutMe)
            && !String.IsNullOrEmpty(member.ScreenName);
    
    Member currentUser = null;
    using (var container = new /**/())
    {
        var images = container.Members.Where(IsSearchable).SelectMany(member => member.Images);
        if (currentUser != null)
            images = images.Concat(currentUser.Images);
    
        var result = images.ToArray();
    }