很抱歉,如果这是一个非常愚蠢的问题,但我无法理解为什么没有填充%html
%head
%title Photogram
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags
%body
%nav.navbar.navbar-default
.navbar-container
.navbar-header
%button.navbar-toggle.collapsed{"data-target" => "#bs-navbar-collapse-1", "data-toggle" => "collapse", type: "button"}
%span.sr-only Toggle Navigation
%span.icon-bar
%span.icon-bar
.navbar-brand= link_to "Photogram", root_path
.collapse.navbar-collapse#bs-navbar-collapse-1
%ul.nav.navbar-nav.navbar-right
%li
= link_to "New Post", new_post_path
%li
= link_to "Login", '#'
%li
= link_to "Register", '#'
.container
= yield
属性。 :
person.Cars
如果我通过var persons = db.Persons.AsNoTracking()
.Select(person => new PersonDto
{
ID = person.ID,
Name = person.SP_Status.Name
});
//The following code where person.Cars is not populated until I write persons.ToList()
foreach (var person in persons)
{
if (person.Name != "Adam")
{
person.Cars = (from ca in db.Cars
where ca.ID == person.ID
select new CarDTO
{
ID = ca.ID,
CarNumber = ca.DocNumber,
}).Distinct()
}
else
{
person.Cars = (from car in db.AnotherCars
where car.ID == person.ID
select new CarDTO
{
ID = car.ID,
CarNumber = car.DocNumber,
}).Distinct()
}
}
实现persons
然后执行填充persons.ToList()
,那么它就能完美运行。但是我在记忆中有一千个物体。
person.Cars
我错过了什么?非常友好地解释并且不要关闭这个问题,这对我来说非常重要。提前谢谢。
我想要做的是根据表//this code works perfectly
persons.ToList();
foreach (var person in persons)
{
if (person.Name != "Adam")
{
person.Cars = (from ca in db.Cars
where ca.ID == person.ID
select new CarDTO
{
ID = ca.ID,
CarNumber = ca.DocNumber,
}).Distinct()
}
else
{
person.Cars = (from car in db.AnotherCars
where car.ID == person.ID
select new CarDTO
{
ID = car.ID,
CarNumber = car.DocNumber,
}).Distinct()
}
}
或person.Cars
中的条件person.Name != "Adam"
填写db.Cars
。
是否可以在不在内存中实现(调用db.AnotherCars
)数据的情况下重写此查询?
答案 0 :(得分:1)
如果您没有运行tolist(),那么在您实际请求数据之前,由于LINQ查询中的延迟/延迟执行,您的查询将不会执行。在大多数情况下,您只有表达式树而不是实际对象。要切换到实际对象,您必须调用tolist()。实质上,您只是添加查询而不是实际请求数据。
答案 1 :(得分:1)
<强>被修改即可。我编辑了一个答案,因为它有错误。
阅读完所有评论后,我认为UNION ALL
两个左连接可以解决这个问题:
Persons
(附加过滤器person.Name != "Adam"
)左连接表Cars
Persons
(附加过滤器person.Name == "Adam"
)左连接表AnotherCars
。 结果行将包含列:
以下是此查询的代码(我使用其他ORM。但我认为它应该适用于EF):
// Getting persons.
var persons = db.Persons
.Where(p => p.ID <= 10) // any of your filtering condition on persons
.Select(p => new { p.ID, p.Name });
// Left join with 'Cars' table
var leftJoin1 = from p in persons.Where(p => p.Name != "Adam")
join c in db.Cars on p.ID equals c.PersonID into j
from c in j.Distinct().DefaultIfEmpty() // do you really need Distinc here?
select new
{
PersonID = p.ID,
PersonName = p.Name,
CarID = c.ID,
CarNumber = c.DocNumber
};
// Left join with 'AnotherCars' table
var leftJoin2 = from p in persons.Where(p => p.Name == "Adam")
join ac in db.AnotherCars on p.ID equals ac.PersonID into j
from ac in j.Distinct().DefaultIfEmpty() // do you really need Distinc here?
select new
{
PersonID = p.ID,
PersonName = p.Name,
CarID = ac.ID,
CarNumber = ac.DocNumber
};
// Resul query
var result = leftJoin1.Concat(leftJoin2)
.OrderBy(r => r.PersonID)
.ThenBy(r => r.CarID)
.ToList();
如果您足以处理4个属性(PersonID, PersonName, CarID, CarNumber
),则需要对其进行分类并在左连接中使用它(而不是select new {}
使用select new YourNewDTO {}
)。
如果你真的需要你的DTO,那么继续。
var personsWithCars = result.GroupBy(p => new { p.PersonID, p.PersonName })
.Select(g => new PersonDTO
{
ID = g.Key.PersonID,
Name = g.Key.PersonName,
Cars = result.Where(r => r.PersonID == g.Key.PersonID)
.Select(r => new CarDTO { ID = r.CarID, CarNumber = r.CarNumber })
.ToList()
});
imho,这是必要的信息:
Ivan Stoev :
persons
是一个查询。当你foreach
它被执行时,那么你 对每个元素做一些事情,但因为你没有存储 结果,你基本上什么都不做。下次你枚举/收费 等人,查询将再次执行,并给你全新的 对象。 但是,如果您删除AsNoTracking
,则可能会获得相同的结果 对象强>
IQueryable<T>
不是List<T>
等存储空间 集合。即使IEnumerable<T>
也不是。例如var q = Enumerable.Range(1, 10).Select(i => new SomeObject { Id = i });
将在您枚举时随时创建新对象。
问:所以这意味着foreach
语句永远不会执行,直到我调用ToList()
方法?
通过 NetMage 回答:不,这意味着每个人对象仅存在于foreach
内一次迭代。在foreach结束时他们都迷失了。