问题
I've been searching all day and can't find a solution to this...
I have an EntityCollection
of Communication
objects which each have an instance of an Intention
object(one-to-one).
I also have a User
object which has many instances of UserLocation
EntityObjects
(one-to-many)
Intention
objects have a propertyUID
.UserLocation
objects have a propertyLID
.I want to write a LINQ expression which returns all
Communication
objects where theUID
property of theIntention
instance associated to aCommunication
object equals ANYLID
property of ANY instance of aUserLocation
instance for aUser
object.
I've tried this
return _context.Communications.Where
(u => u.Intention.UID.Equals
(user.UserLocations.Select
(p => p.LID)));
and this
return _context.Communications.Where
(u => user.UserLocations.Any
(x => x.LID.Equals
(u.Intention.UID)));
and this
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()));
and this
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications.Where(x=> lidlist.Contains(x.Intention.UID)).ToList();
(this gives me an error on the Contains statement saying "Delegate System.Func<Communication,int,bool>
does not take 1 argument", don't know how to fix)
Along with all these variations I have also:
- modified my method to return
IQueryable<Communication>
and have also triedList<Communication>
while appendingToList()
to my queries.
Nothing works. Regardless of what I try I always end up with this exception
NotSupportedException was unhandled by user code
Unable to create a constant value of type 'PreparisCore.BusinessEntities.UserLocation'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
What am i doing wrong??
回答1:
Given this code:
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
}
}
I get this result:
Communication-> Intention:2
Communication-> Intention:3
Am I missing anything?
回答2:
From the last two compiler errors you have linked in one of your comments...

...I would conclude that Intention.UID
is a nullable type int?
and not a not-nullable int
as you said in the comments. This indeed doesn't compile. Try to change your last query to:
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications
.Where(x => x.Intention.UID.HasValue
&& lidlist.Contains(x.Intention.UID.Value))
.ToList();
The other three queries do not work because user.UserLocations
is a collection of a non-primitive custom type in memory (for the SQL query to be generated it is a "constant" value) and EF doesn't support to build a SQL query with such a constant custom type.
来源:https://stackoverflow.com/questions/11729384/returning-a-collection-of-objects-where-an-objects-property-matches-any-property