Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以使用公共查询扩展实体模型?_C#_Asp.net Mvc 3_Linq_Entity Framework 4 - Fatal编程技术网

C# 是否可以使用公共查询扩展实体模型?

C# 是否可以使用公共查询扩展实体模型?,c#,asp.net-mvc-3,linq,entity-framework-4,C#,Asp.net Mvc 3,Linq,Entity Framework 4,假设我有一组网站,其中有一组用户。每当我必须重新定义查询以获取(比如)给定站点的上次访问用户时,我发现自己违反了DRY原则 例如,我的查询可能如下所示: from site in Context.Sites where site.ID == 99 select new { ID = site.ID, Name = site.Name, URL = site.URL, LastVisitedUser = site.Users.OrderByDescending(u => u.

假设我有一组
网站
,其中有一组
用户
。每当我必须重新定义查询以获取(比如)给定
站点的上次访问
用户时,我发现自己违反了DRY原则

例如,我的查询可能如下所示:

from site in Context.Sites
where site.ID == 99
select new {
  ID = site.ID,
  Name = site.Name,
  URL = site.URL,
  LastVisitedUser = site.Users.OrderByDescending(u => u.LastVisited).Select(u => new {
      ID = u.ID,
      Username = u.Username,
      Email = u.EmailAddress
   })
   .FirstOrDefault()
}
from site in Context.Sites
where site.ID == 99
select new SiteViewModel {
  ID = site.ID,
  Name = site.Name,
  URL = site.URL,
  LastVisitedUser = site.LastVisitedUser <--- NOTE    
}
该查询返回我想要的结果,但我发现自己在多个地方重复了对LastVisitedUser的相同选择,因为我正在以不同的方式选择站点以填充各种ViewModels

所以,我想我应该简单地用如下属性扩展我的Site Entitiy类:

public partial class Site {
  public LastVisitedUser {
    get {
      var query = from user in Users
                  where user.SiteID == this.ID
                  orderby user.LastVisited descending
                  select user;
      return query.FirstOrDefault()
    }
  }
}
以这种方式,每当我选择一个站点时,获取这个属性就相当简单了。这几乎可以实现,但是我一直在尝试将实体用户分配到我的UserViewModel属性中,并将其分配到我的return的LastVisited属性中,对于如何将
用户
投影到我的ViewModel版本中,我没有一个明显的方法

也许举个例子可以帮助解释。我想实现的是这样的目标:

from site in Context.Sites
where site.ID == 99
select new {
  ID = site.ID,
  Name = site.Name,
  URL = site.URL,
  LastVisitedUser = site.Users.OrderByDescending(u => u.LastVisited).Select(u => new {
      ID = u.ID,
      Username = u.Username,
      Email = u.EmailAddress
   })
   .FirstOrDefault()
}
from site in Context.Sites
where site.ID == 99
select new SiteViewModel {
  ID = site.ID,
  Name = site.Name,
  URL = site.URL,
  LastVisitedUser = site.LastVisitedUser <--- NOTE    
}
来自上下文中的站点。站点
其中site.ID==99
选择新的SiteViewModel{
ID=site.ID,
Name=site.Name,
URL=site.URL,

LastVisitedUser=site.LastVisitedUser编辑:前一个答案不正确。您不能在导航属性上使用扩展方法,但仍然可以为整个
站点
投影创建扩展方法

只需创建简单的可重用扩展方法:

public static IQueryalbe<SiteModel> GetSiteModels(this IQueryable<Site> query)
{
    return query.Select(site => new SiteModel {
                     ID = site.ID,
                     Name = site.Name,
                     URL = site.URL,
                     LastVisitedUser = site.Users
                                           .OrderByDescending(u => u.LastVisited)
                                           .Select(u => new LastVisitedUser {
                                                ID = u.ID,
                                                Username = u.Username,
                                                Email = u.EmailAddress
                                            }});
}

您的示例将不起作用,因为您的属性对于Linq to实体不可见。

编辑:前面的答案不正确。您不能在导航属性上使用扩展方法,但仍然可以为整个
站点创建扩展方法

只需创建简单的可重用扩展方法:

public static IQueryalbe<SiteModel> GetSiteModels(this IQueryable<Site> query)
{
    return query.Select(site => new SiteModel {
                     ID = site.ID,
                     Name = site.Name,
                     URL = site.URL,
                     LastVisitedUser = site.Users
                                           .OrderByDescending(u => u.LastVisited)
                                           .Select(u => new LastVisitedUser {
                                                ID = u.ID,
                                                Username = u.Username,
                                                Email = u.EmailAddress
                                            }});
}

您的示例将不起作用,因为您的属性对于Linq to实体不可见。

如果您的意思是要重用具有不同扩展名的常见查询,您只需编写一些基本查询并获得不同的结果和一些Where lambda表达式。如果您对其进行分析,您将看到只有一个查询需要DB just retu基本查询中的iqerable

如果您的意思是要重用具有不同扩展名的常见查询,您只需编写一些基本查询,并获得不同的结果和一些Where lambda表达式。如果您对其进行分析,您将看到您只有一个对DB的查询,而在基本查询中只返回iqerable

是否调用了这些方法我的存储库中。我的控制器正在处理IEnumerable变量或具体对象。这些方法是从控制器调用的,还是在哪一层上需要这些查询?在我的存储库中。我的控制器正在处理IEnumerable变量或具体对象s、 我一直在尝试这一点,但无论我做什么,我总是会遇到一个错误:EntityCollection不包含GetLastUsers()的定义并且找不到接受EntityCollection类型的第一个参数的扩展方法。我甚至在我的存储库类中放置了扩展方法,以确保我没有弄乱名称空间或其他东西。我是否遗漏了什么?没错,它不起作用,因为表达式方法不能在导航属性的投影中使用y、 您必须为整个站点投影创建扩展方法。我一直在尝试此方法,但无论我做什么,都会遇到一个错误:EntityCollection不包含GetLastUsers()的定义并且找不到接受EntityCollection类型的第一个参数的扩展方法。我甚至在我的存储库类中放置了扩展方法,以确保我没有弄乱名称空间或其他东西。我是否遗漏了什么?没错,它不起作用,因为表达式方法不能在导航属性的投影中使用y、 必须为整个场地投影创建扩展方法。