示例情况(我已经更直接地询问了这个并且没有收到反馈,所以请原谅抽象示例,但我只是想更好地提出问题):
为简洁起见(实际模型有数百行)。数据库被建模为代表房屋。房子可以有房间,窗户和院子。客房配有家具或电子设备。家具可以是沙发,桌子或椅子。沙发具有图案,材料和尺寸。
先生。 F. Bar的房子是Bar's Crazy Couches的展示厅。每个月Bar先生的房间都会展示数百张沙发。 Bar先生喜欢知道人们什么时候喜欢他的沙发,并且每个房间的设置都会得到反馈。
先生。 Bar先生的兄弟Ed负责管理他的数据库管理系统。艾德先生决定拆除一段时间没用过的沙发!
假设此删除被接受或存档,或放在分区中,或标记为非活动状态(即它未被阻止,这是一个选项)。
如何在房屋中确定是否缺少这个依赖沙发,房间中有一个房间使用Entity Framework 4.1从linq查询引用移除的沙发?
调用查询可能看起来像这样(为了简洁起见,我只留下了主题部分),但它会有一个很难捕获的异常。
public House getHouse(object id){
using( DbContext context = new FooBarContext()){
DbSet<House> dbSet = context.Set<House>();
IQueryable<House> query = dbSet;
query = query.Where(h => h.HouseKey == id);
query = query.Include(h => h.Room);
query = query.Include(h => h.Room.Couch);
}
return query.ToList();
}
var house = getHouse(9).FirstOrDefault();
房子将填满正确的房子。它将包括适当的房间。但是,一个房间会引用一张破损的沙发。到目前为止,任何try{}catch{}
都将导致没有异常被捕获。这仅适用于索引号为9的房子。在代码中,这可以很容易地列出许多不同的房屋构成。
如何确保包含拆除沙发的房间的房屋被抓住?
答案 0 :(得分:1)
正如您可能想象的那样,这不会很漂亮。基本上,你必须做一个左连接,然后从所有房屋/房间返回所有沙发。当您尝试访问坏沙发时,您将获得SystemException
:
A relationship multiplicity constraint violation occurred:
An EntityReference expected at least one related object,
but the query returned no related objects from the data store.
try
{
var test = (from h in context.Set<House>()
join r in context.Set<Room>()
on h.Room.Id equals r.Id into houseRoom
from joinHouseRoom in houseRoom.DefaultIfEmpty()
join c in context.Set<Couch>()
on r.Couch.Id equals c.Id into houseRoomCouch
from joinHouseRoomCouch in houseRoomCouch.DefaultIfEmpty()
select h).ToList()
.Select(x => x.Room.Couch.Material)
.ToList();
}
catch(SystemException se)
{
Console.WriteLine(se.Message);
}