2017-04-26 166 views
1

无法想出一个好标题,因为我不知道的名字我后:)实体框架的核心 - 许多一对多“影子查询”

我的域名

public class Profile 
{ 
    public int Id { get; set } 

    // Many-to-many using CLR join class 
    public virtual IList<Youtubes> Youtubes { get; set; } 
} 

public class Youtubes 
{ 
    public int YoutubeId { get; set; } 
    public int ProfileId { get; set; } 
    public bool IsPrimary { get; set; } 
    // Virtual properties omitted 
} 

只有一个通道可以被标记为IsPrimary(这是不可能在数据库级别使用当前设计强制执行:)。

我有一个需求,我需要对Youtube上定义的属性进行排序,即Cost是可以为空的int,我正在努力完成这项工作。在这种特殊情况下,我只关心那些主要的(至少在写这篇文章时这种要求是这样的)。

排序表达式定义为

public Expression<Func<Profile, int>> Exp() 
{ 
    return p => (p.Blog.Cost ?? 0) + (p.Instagram.Cost ?? 0) + 
      (p.Youtube.Cost ?? 0); // This was prior to adding many-to-many 
} 

我想要做的就是

public Expression<Func<Profile, int>> Exp() 
{ 
    return p => (p.Blog.Cost ?? 0) + (p.Instagram.Cost ?? 0) + 
      (p.Youtubes.FirstOrDefault(y => i.IsPrimary)?.Cost ?? 0); 
} 

但是,这是不允许的表达式树内。那么如何解决这个问题呢?

目前倾向于创建一个ProfileYouTubePrimary,它将建立Profile - > Youtubes - > Primary之间的零对一关系,因此我可以强制在数据库级别最多有一个主要通道,并且在相同我的表达式树中的属性的引用。

输入greately赞赏

回答

2

嗯,这不是那么简洁,但你可以Where + Select + FirstOrDefault(没有谓词版本)替换它:

public Expression<Func<Profile, int>> Exp() 
{ 
    return p => (p.Blog.Cost ?? 0) + (p.Instagram.Cost ?? 0) + 
     p.Youtubes.Where(y => y.IsPrimary).Select(y => y.Cost ?? 0).FirstOrDefault(); 
} 
+1

我怎么能错过 - 谢谢! – joacar