使用 Linq to Entities (EF4.0) 进行 IN 和 NOT IN

发布于 2024-10-26 04:07:34 字数 1533 浏览 1 评论 0原文

这几天来这已经毁了我的生活,是时候问问了...

我正在为我的应用程序使用 Entity Framework 4.0。

位置(例如房屋或办公室)具有一个或多个设施(例如浴室、卧室、台球桌等..)

我想在位置页面上显示一个复选框列表,其中包含设施的复选框列表,以及检查当前位置是否有。

我的设施视图模型是这样的...

public class FacilityViewItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Checked { get; set; }
}

因此,当我将位置视图模型传递给 UI 时,我想传递设施的 List ,其中 T 的类型为 FacilityViewItem。

要获取该位置已有的设施很简单 - 我使用 Location.Facilities 进行查询,该查询返回一个 EntityCollection,其中 T 的类型为 Facility。这是因为设施是导航属性......

var facs = from f in location.Facilities
select new FacilityViewItem()
{
    Id = f.FacilityId,
    Name = f.Name,
    Checked = true
};

所以这就是我的问题所在 - 我想要其余的设施,即该位置没有的设施。

我尝试过使用 except() 、 Any() 和 Contains() 但出现同样的错误。

不起作用的查询示例...

var restOfFacilities = from f in ctx.Facilities
    where !hasFacilities.Contains(f)
    select new FacilityViewItem()
        {
            Id = f.FacilityId,
            Name = f.Name
        };

var restOfFacilities = ctx.Facilities.Except(facilitiesThatLocationHas);

var notFacs = from e in ctx.Facilities
where !hasFacilities.Any(m => m.FacilityId == e.FacilityId)
    select new FacilityViewItem()
        {
            Id = e.FacilityId,
            Name = e.Name
        };

以及我在每个实现中遇到的错误...

System.NotSupportedException 未处理 消息=无法创建“Chapter2ConsoleApp.Facility”类型的常量值。此上下文仅支持原始类型(“例如 Int32、String 和 Guid”)。

我在这里忽略了什么?

This has been ruining my life for a few days now, time to ask...

I am using Entity Framework 4.0 for my app.

A Location (such as a house or office) has one or more facilities (like a bathroom, bedroom, snooker table etc..)

I want to display a checkbox list on the location page, with a checkbox list of facilities, with the ones checked that the location currently has.

My View Model for the facilities goes like this...

public class FacilityViewItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Checked { get; set; }
}

So when im passing the Location View Model to the UI, i want to pass a List<T> of facilities where T is of type FacilityViewItem.

To get the facilities that the location already has is simple - i make a query using Location.Facilities which returns an EntityCollection where T is of type Facility. This is because Facilities is a navigation property....

var facs = from f in location.Facilities
select new FacilityViewItem()
{
    Id = f.FacilityId,
    Name = f.Name,
    Checked = true
};

So here is where my problem lies - i want the rest of the facilities, the ones that the Location does not have.

I have tried using Except() and Any() and Contains() but i get the same error.

Examples of queries that do not work...

var restOfFacilities = from f in ctx.Facilities
    where !hasFacilities.Contains(f)
    select new FacilityViewItem()
        {
            Id = f.FacilityId,
            Name = f.Name
        };

var restOfFacilities = ctx.Facilities.Except(facilitiesThatLocationHas);

var notFacs = from e in ctx.Facilities
where !hasFacilities.Any(m => m.FacilityId == e.FacilityId)
    select new FacilityViewItem()
        {
            Id = e.FacilityId,
            Name = e.Name
        };

And the error i get with every implementation...

System.NotSupportedException was unhandled
Message=Unable to create a constant value of type 'Chapter2ConsoleApp.Facility'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

What am i overlooking here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故人爱我别走 2024-11-02 04:07:34

具有讽刺意味的是,经过几天的痛苦,我在这里发布问题后几个小时内就解决了这个问题。

该错误基本上是说“我不知道如何通过比较强类型对象来计算不包含哪些项目。”给我一个整数列表或一些简单类型,我可以处理它”。

因此,首先您需要获取主键列表,然后在 contains 子句中使用它......

//get the primary key ids...
var hasFacilityIds = from f in hasFacilities
    select f.FacilityId;

//now use them in the contains clause...
var restOfFacilities = from f in ctx.Facilities
    where !hasFacilityIds.Contains(f.FacilityId)
        select new FacilityViewItem()
            {
                Id = f.FacilityId,
                Name = f.Name
            };

ironically enough i solved it in a matter of hours after i posted the question on here, after days of suffering.

The error is basically saying 'i dont know how to calculate what items are not included by comparing strongly typed objects. Give me a list of Ints or some simple types, and i can take care of it'.

So, first you need to get a list of the primary keys, then use that in the contains clause...

//get the primary key ids...
var hasFacilityIds = from f in hasFacilities
    select f.FacilityId;

//now use them in the contains clause...
var restOfFacilities = from f in ctx.Facilities
    where !hasFacilityIds.Contains(f.FacilityId)
        select new FacilityViewItem()
            {
                Id = f.FacilityId,
                Name = f.Name
            };
醉南桥 2024-11-02 04:07:34

第一个查询看起来不错,但您需要比较 Id

var restOfFacilities = from f in ctx.Facilities
                       where !facs.Select(fac => fac.Id).Contains(f.Id)
                       select f;

The first query seems fine, but you need to compare the Ids:

var restOfFacilities = from f in ctx.Facilities
                       where !facs.Select(fac => fac.Id).Contains(f.Id)
                       select f;
孤独陪着我 2024-11-02 04:07:34

无论如何,我想看看 hasFacilities 是什么,正如 L2E 所示,“在此上下文中仅支持原始类型('例如 Int32、String 和 Guid')”,所以我想您必须首先检索数据并将其放入一个集合中FacilityViewItem。

var restOfFacilities = ctx
    .Facilities
    .Where(f => !hasFacilities.Contains(f))
    .Select(f => new { f.FacilityId, f.Name })
    .ToList()
    .Select(f => new FacilityViewItem {
        Id = f.FacilityId,
        Name = f.Name
    });

var notFacs = ctx
    .Facilities
    .Where(e => !hasFacilities.Any(m => m.FacilityId == e.FacilityId))
    .Select(e => new { e.FacilityId, e.Name })
    .ToList()
    .Select(e => new FacilityViewItem {
        Id = e.FacilityId,
        Name = e.Name
    });

希望有帮助

I wanna see what's hasFacilities, anyway, as L2E shows, "Only primitive types ('such as Int32, String, and Guid') are supported in this context", so I suppose you must retrieve first the data and put into a collection of FacilityViewItem.

var restOfFacilities = ctx
    .Facilities
    .Where(f => !hasFacilities.Contains(f))
    .Select(f => new { f.FacilityId, f.Name })
    .ToList()
    .Select(f => new FacilityViewItem {
        Id = f.FacilityId,
        Name = f.Name
    });

var notFacs = ctx
    .Facilities
    .Where(e => !hasFacilities.Any(m => m.FacilityId == e.FacilityId))
    .Select(e => new { e.FacilityId, e.Name })
    .ToList()
    .Select(e => new FacilityViewItem {
        Id = e.FacilityId,
        Name = e.Name
    });

hope it helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文