Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.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# 使用LINQ to Entities返回一个对象集合,其中一个对象属性与另一个对象集合中的任何属性相匹配_C#_Linq_Entity Framework_Linq To Entities_Entitycollection - Fatal编程技术网

C# 使用LINQ to Entities返回一个对象集合,其中一个对象属性与另一个对象集合中的任何属性相匹配

C# 使用LINQ to Entities返回一个对象集合,其中一个对象属性与另一个对象集合中的任何属性相匹配,c#,linq,entity-framework,linq-to-entities,entitycollection,C#,Linq,Entity Framework,Linq To Entities,Entitycollection,我已经搜索了一整天,找不到解决这个问题的方法 我有一个EntityCollection的Communication对象,每个对象都有一个意图对象的实例(一对一) 我还有一个User对象,它有许多UserLocationEntityObjects(一对多)的实例 Intention对象具有属性UID UserLocation对象有一个属性LID 我想编写一个LINQ表达式,它返回所有Communication对象,其中与Communication对象关联的Intention实例的UID属性等于用

我已经搜索了一整天,找不到解决这个问题的方法

我有一个
EntityCollection
Communication
对象,每个对象都有一个
意图
对象的实例(一对一)

我还有一个
User
对象,它有许多
UserLocation
EntityObjects
(一对多)的实例

  • Intention
    对象具有属性
    UID
  • UserLocation
    对象有一个属性
    LID

  • 我想编写一个LINQ表达式,它返回所有
    Communication
    对象,其中与
    Communication
    对象关联的
    Intention
    实例的
    UID
    属性等于
    用户的
    实例的任何
    LID
    属性反对

我试过这个

return _context.Communications.Where
(u => u.Intention.UID.Equals
(user.UserLocations.Select
(p => p.LID)));
还有这个

return _context.Communications.Where
(u => user.UserLocations.Any
(x => x.LID.Equals
(u.Intention.UID)));
还有这个

var thislist = from Intentions in _context.Intentions
                           join UserLocations in user.UserLocations
                           on Intentions.UID equals UserLocations.LID
                           select Intentions.UID;
            return _context.Communications.Where(u => u.Intention.Equals(thislist.Any()));
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications.Where(x=> lidlist.Contains(x.Intention.UID)).ToList();
还有这个

var thislist = from Intentions in _context.Intentions
                           join UserLocations in user.UserLocations
                           on Intentions.UID equals UserLocations.LID
                           select Intentions.UID;
            return _context.Communications.Where(u => u.Intention.Equals(thislist.Any()));
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications.Where(x=> lidlist.Contains(x.Intention.UID)).ToList();
(这在Contains语句中给出了一个错误,该语句表示“Delegate
System.Func
不接受1个参数”,不知道如何修复)

除了所有这些变化,我还:

  • 修改了我的方法以返回
    IQueryable
    ,并且在将
    ToList()
    附加到我的查询时尝试了
    List
什么都不管用。不管我怎么做,我总是以这个例外而告终

NotSupportedException未经用户代码处理

无法创建“PreparisCore.BusinessEntities.UserLocation”类型的常量值。在此上下文中仅支持基本类型(“如Int32、字符串和Guid”)。

我做错了什么???

鉴于以下代码:

namespace CollectionsWithIntentions
{
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;

    internal class Program
    {
        #region Methods

        private static void Main(string[] args)
        {
            var communications = new[]
                {
                    new Communication { Intention = new Intention { UID = 1 } },
                    new Communication { Intention = new Intention { UID = 2 } },
                    new Communication { Intention = new Intention { UID = 3 } },
                    new Communication { Intention = new Intention { UID = 4 } },
                };
            var users = new[]
                {
                    new User { UserLocations = new List<UserLocation>(new[] { new UserLocation { LID = 2 },new UserLocation{LID=5}  }) },
                    new User { UserLocations = new List<UserLocation>(new[] { new UserLocation { LID = 3 } }) }
                };

            IEnumerable<Communication> res =
                communications.Where(w => users.Any(a => a.UserLocations.Any(b=>b.LID == w.Intention.UID)));
            foreach (Communication communication in res)
            {
                Trace.WriteLine(communication);
            }
        }

        #endregion
    }

    internal class Communication
    {
        #region Public Properties

        public Intention Intention { get; set; }

        #endregion

        #region Public Methods and Operators

        public override string ToString()
        {
            return string.Concat("Communication-> Intention:", this.Intention.UID);
        }

        #endregion
    }

    internal class Intention
    {
        #region Public Properties

        public int UID { get; set; }

        #endregion
    }

    internal class User
    {
        #region Public Properties

        public List<UserLocation> UserLocations { get; set; }

        #endregion
    }

    internal class UserLocation
    {
        #region Public Properties

        public int LID { get; set; }

        #endregion
    }
}

我遗漏了什么吗?

您在其中一条评论中链接的最后两个编译器错误

…我认为,
Intention.UID
是一种可为空的类型
int?
,而不是您在评论中所说的不可为空的
int
。这确实无法编译。尝试将上一个查询更改为:

var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications
    .Where(x => x.Intention.UID.HasValue
             && lidlist.Contains(x.Intention.UID.Value))
    .ToList();

其他三个查询不起作用,因为
user.UserLocations
是内存中非原始自定义类型的集合(对于要生成的SQL查询,它是一个“常量”值),EF不支持使用这种常量自定义类型构建SQL查询。

UID和LID的类型是什么?嗯,第二种形式应该可以工作。为了清楚起见,我会使用=。我将尝试编写一个测试用例来确认。哪个委托不接受1个参数?通常,异常会精确地指定委托类型。您的方法返回什么类型?在我看来,最后一个代码应该有效。其他三个确实不起作用。我想我发现了第二个表格的问题。。。BRB@SlaumaSystem.FuncOne更正,我只搜索了一个用户,但您的代码看起来与我的第二个示例几乎完全相同。需要注意的另一个区别是,所有这些对象都是EntityObjects(用户位置、用户、通信、意图)或EntityCollections(用户位置)。UserLocations是两个实体“User”和“Location”之间的“桥接”对象。我可以确认通过EF会导致遇到相同的错误。。。调查答案在这本书中。因此,在您的情况下,首先必须将通信和用户位置强制转换到列表中。它的工作原理是:ctx.Communications.ToList().Where(w1=>user.Locations.ToList().Any(a1=>a1.LID==w1.intentials.UID)).ToList();你太棒了:)就是这样!我觉得把正手和正手结合在一起很合适。谢谢你的帮助@MattFoxxDuncan和Darek:注释中的解决方案非常糟糕,因为它将在应用过滤器之前首先将整个
通信
表加载到内存中。对于该表中的100条记录来说可能不是问题,但对于100000条或一百万条记录来说可能不是问题?