我正在学习实体框架,我遇到了问题!
有人可以澄清我是否正确地认为我无法从数据库中获取父母及其子集的子集?
例如...
db.Parents
.Include(p => p.Children)
.Where(p => p.Children.Any(c => c.Age >= 5))
Run Code Online (Sandbox Code Playgroud)
这将返回所有有5岁以上孩子的父母,但如果我遍历Parents.Children集合,所有孩子都将在场(不仅仅是5岁以上的孩子).
现在查询确实对我有意义(我已经要求包含子项,我已经得到了它们!),但可以想象我想在某些场景中将where子句应用于子集合.
问题:
我找到了一些关于这个主题的博客和SO帖子,但没有什么能够解释我的小脑袋.
编辑
读过这个博客(感谢Daz Lewis).......我仍然没有得到它!
在博客中给出的示例中,我可以看到如何针对单个Parent实例实现它,但我正在努力弄清楚如何使用集合来实现它.
我怎么能得到一个IEnumerable,其中每个父母都有一个过滤的儿童集合(年龄> = 5)?
进一步澄清:
在回答DonAndre的评论时,我追问的是a)有5岁以上孩子的父母名单(仅包括那些孩子).
任何帮助,赞赏,
谢谢.
我正在尝试过滤初始查询.我已经嵌套了包含模型的叶子.我正在尝试根据其中一个包含的属性进行过滤.例如:
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();
}
Run Code Online (Sandbox Code Playgroud)
我怎么能说呢.Where(w => w.post.Author == "me")?
我已经看到了类似问题的一些答案,但我似乎无法弄清楚如何将答案应用于我的问题.
var allposts = _context.Posts
.Include(p => p.Comments)
.Include(aa => aa.Attachments)
.Include(a => a.PostAuthor)
.Where(t => t.PostAuthor.Id == postAuthorId).ToList();
Run Code Online (Sandbox Code Playgroud)
附件可以由作者(类型作者)或贡献者(类型贡献者)上传.我想要做的是,只获取附件所有者属于作者类型的附件.
我知道这不起作用并给出错误:
.Include(s=>aa.Attachments.Where(o=>o.Owner is Author))
Run Code Online (Sandbox Code Playgroud)
我在这里读过Filtered Projection
编辑 - 链接到文章:: http://blogs.msdn.com/b/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx ,
但我无法理解它.
我不想在最后的where子句中包含过滤器,因为我想要所有帖子,但我只想检索属于作者的那些帖子的附件.
编辑2: - 请求发布模式
public abstract class Post : IPostable
{
[Key]
public int Id { get; set; }
[Required]
public DateTime PublishDate { get; set; }
[Required]
public String Title { get; set; }
[Required]
public String Description { get; set; }
public Person PostAuthor { get; …Run Code Online (Sandbox Code Playgroud) 我目前在我的应用程序中有这个LINQ/EF代码:
var rootCategoryItem = DatabaseContext.Categories
.Include("SubCategories")
.OrderBy(c => c.CategoryOrder)
.Single(c => c.CategoryId == 1);
Run Code Online (Sandbox Code Playgroud)
我知道在EF你不能过滤器中包含的项目着呢,我可以写一些代码LINQ过滤掉不需要的子类别...但LINQ代码将被转换成一个可怕的SQL是高度未优化.我也可以编写一个执行此操作的存储过程(并编写比LINQ更好的查询),但我真的想使用纯EF.
所以我留下了两个选项(除非有人可以看到其他选项).
第一个是遍历子类别,删除不需要的子类别:
var subCategoriesToFilter = rootCategoryItem.SubCategories.ToList();
for (int i = 0; i < subCategoriesToFilter.Count; i++)
{
if (subCategoriesToFilter[i].Deleted)
rootCategoryItem.SubCategories.Remove(subCategoriesToFilter[i]);
}
Run Code Online (Sandbox Code Playgroud)
第二种选择是在我看来:
<ul class="treeview ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion ui-widget ui-sortable ui-accordion-content-active">
@foreach (var categoryitem in Model.SubCategories.OrderBy(c => c.CategoryOrder))
{
@if(!Model.Deleted)
{
<li class="treelistitem" id="@Model.CategoryId">
<div class="ui-accordion-header ui-state-default ui-corner-all ui-accordion-icons ui-sortable-handle first">
<span class="clickable">
<span class="ui-accordion-header-icon ui-icon treeviewicon treeviewplus"></span>
<i class="glyphicon glyphicon-folder-open rightfolderpadding"></i><span class="categoryname">@Model.CategoryName</span>
</span>
</div> …Run Code Online (Sandbox Code Playgroud) 这是我的表达:
Course course = db.Courses
.Include(
i => i.Modules.Where(m => m.IsDeleted == false)
.Select(s => s.Chapters.Where(c => c.IsDeleted == false))
).Include(i => i.Lab).Single(x => x.Id == id);
Run Code Online (Sandbox Code Playgroud)
我知道原因在于Where(m => m.IsDeleted == false)模块部分,但为什么会导致错误?更重要的是,我该如何解决?
如果我删除where子句它工作正常,但我想过滤掉已删除的模块.
我在LINQ查询中为包含的项添加一些过滤条件有些困难.我的查询是这样的
var item = _Context.Order.Include("Inner")
.Include("Inner.first")
.Include("Inner.second")
.Where(x => ( !(x.IsDeleted) && (x.IsActive) &&
(x.itemid == id))).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,"Inner"是另一个项目列表.现在我需要过滤内部项目.我只需要内部项目,过滤条件为inner.isDeleted = true.
查询应该返回一个类,
public class Order
{
public string Name { get; set; }
public List<InnerDetails> Inner{ get; set; }
public bool IsDeleted { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和InnerDetails类一样
public class InnerDetails
{
public string Sample { get; set; }
public bool IsDeleted { get; set; }
public int firstId { get; set; }
public int secondID { get; set; }
public …Run Code Online (Sandbox Code Playgroud) 我试图取代我的大丑陋查询; 虽然丑陋但它可以按预期工作: -
using (var ctx = new Data.Model.xxxTrackingEntities())
{
var result = ctx.Offenders
.Join(ctx.Fees, o => o.OffenderId, f => f.OffenderId,
(o, f) => new { Offenders = o, Fees = f })
.Join(ctx.ViolationOffenders, o => o.Fees.ViolationId, vo => vo.ViolationId,
(o, vo) => new { Offenders = o, ViolationOffenders = vo })
.Join(ctx.Violations, v => v.ViolationOffenders.ViolationId, vo => vo.ViolationId,
(v, vo) => new { Violations = v, ViolationOffenders = vo })
.Where(o => o.Violations.Offenders.Offenders.YouthNumber != "")
.ToList();
gvwData.DataSource = result; …Run Code Online (Sandbox Code Playgroud) 我正在使用EF5,当关系为1:N时,如果我想加载相关实体,我会执行以下操作:
使用T-SQL,我从数据库加载带有T-SQL的主要实体,如下所示:
select *
from MainEntities
where ...
Run Code Online (Sandbox Code Playgroud)使用T-SQL我加载相关的实体
select *
from RelatedEntities
where IDMainEntity IN (---)
Run Code Online (Sandbox Code Playgroud)此时,EF使用相关实体填充主要实体的属性导航.另外,在每个实体的类型的本地属性中,dbContext我拥有每种类型的所有实体.
但是,如果我使用N:N关系做同样的事情,我没有关系中间表的实体,当我执行查询时,我在dbContext每个类型的实体的本地执行,但是未填充属性导航.
我想知道为什么以及它是否存在替代方案.
我使用这种方式是因为我想使用T-SQL来创建动态查询.如果我使用预先加载,那么动态查询的灵活性与使用TSQL时不同,效率较低.如果我使用显式加载我做N个额外的查询,主要实体的结果中的每个记录之一用我的方式,我只有一个额外的查询,因为我一次得到所有相关的实体.如果我使用延迟加载我有同样的问题,N个额外的查询.
当关系为N:N时,为什么EF不会填充相关属性?
谢谢.
我正在建立一个论坛,每个帖子都可以发表评论。
我想加载一批N个帖子,因此每个帖子都加载前K条评论。
我已经从此代码开始,但是目前每个帖子都包含所有评论。如何仅在每个帖子中加载前K条评论,而不必对数据库进行K条调用?
List<ForumPost> result = ctx
.ForumPosts
.Include("Comments") // <-- ??? How to take first K ???
.Where(i => i.Thread.ID == threadID)
.OrderByDescending(i => i.Date)
.Take(N).ToList();
Run Code Online (Sandbox Code Playgroud)
谢谢!
我在实体之间有以下关系.公司1 ---*任命*--- 1名员工
我在单独的数据库中有.net asp成员资格.无论何时创建用户,都可以将其分配给公司,员工或管理员角色.
在我的公司控制器的索引操作中,我检查登录用户的角色.根据角色,我做了不同的linq查询.例如,管理员可以获得所有公司的列表,公司可以获得具有与User.Identity.Name相同的用户名属性(字符串)的公司列表.对于管理员和公司角色,它工作正常.
对于employees角色,我想加载与当前员工相关的所有公司.我很难编写一个执行此工作的linq查询.
我试过了
var companies = db.Companies.Include(c => c.Appointments.Select(a=>a.Employee).Where(e=>e.Username.ToLower() == this.User.Identity.Name.ToLower())).ToList();
Run Code Online (Sandbox Code Playgroud)
我得到这个错误"Include路径表达式必须引用在类型上定义的导航属性.使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性.参数名称:path"
这是源代码,
CompanyController
[Authorize]
public class CompanyController : Controller
{
private MyDBContext db = new MyDBContext();
//
// GET: /Company/
public ViewResult Index()
{
var viewModel = new CompanyIndexViewModel();
if (Roles.IsUserInRole("administrators")) {
viewModel = new CompanyIndexViewModel { Companies = db.Companies.ToList() };
}
else if (Roles.IsUserInRole("companies")) {
viewModel = new CompanyIndexViewModel { Companies = db.Companies.Where(c => c.Username.ToLower().Equals(this.User.Identity.Name.ToLower())).ToList() };
}
else if (Roles.IsUserInRole("employees")) {
var companies …Run Code Online (Sandbox Code Playgroud) 我被这个 linq 查询困住了。
我有这张桌子。
ID A B C D
1 some data
2 some other data
Run Code Online (Sandbox Code Playgroud)
然后,对于该表上的每条记录,我可能没有或许多行
ID TableA_ID R
1 1 1
2 1 2
3 1 5
4 2 2
Run Code Online (Sandbox Code Playgroud)
例如。第 1 行(某些数据)在表 B 上有 3 行。
我尝试使用
tableA.Include(x => x.tablebchilds.Where( d => d.R == 1)).ToList()
Run Code Online (Sandbox Code Playgroud)
但它不起作用。与许多其他变化。
此查询的目标是返回tableA.row#1,如果我将它1作为值(值R)传递。Number <> 2不会给出任何结果。
表格在 EF 上链接。所以TableB.tableA_ID是的外键tableA.ID
编辑 #1
我在没有运气的情况下尝试了标记为重复的问题中的答案。如果用户插入1作为参数,则给出 2 tableA.rows ,linq 查询应返回Row #1, some data。如果 …