Я пытаюсь преобразовать старый необработанный запрос SQL в Linq с Платформой Объекта здесь.
Это использовало оператор IN с набором объектов. Запрос был чем-то как этот:
SELECT Members.Name
FROM Members
WHERE Members.ID IN ( SELECT DISTINCT ManufacturerID FROM Products WHERE Active = 1)
ORDER BY Members.Name ASC
Так как возврат подзапроса не является ни одной строкой, но набором строк, которые я не могу использовать String.Contains()
метод.
Я думал о выполнении чего-то как:
var activeProducts = (
from products in db.ProductSet
where product.Active == true
select product.ManufacturerID);
и затем
var activeMembers = (
from member in db.ContactSet
where member.ID.ToString().Contains(activeProducts));
но это останавливается в, содержит высказывание, что это имеет недействительные аргументы... Я не могу выбрать activeProducts. ManufacturerID, потому что, очевидно, свойство не там, так как он возвращает IQueryable...
Нижняя строка, что я пытаюсь сделать здесь, состоит в том, чтобы возвратить список участников, у которых есть по крайней мере один активный продукт.
Какая-либо подсказка?
[править]
Вот полный код запроса... Я попробовал содержанием по второму выражению, Linq, казалось, не нравилось оно:
Server Error in '/' Application. LINQ to Entities does not recognize the method 'Boolean Contains[String](System.Linq.IQueryable``1[System.String], System.String)' method, and this method cannot be translated into a store expression.
var activeProduct =(from product in Master.DataContext.ProductSet
where product.Active == true
&& product.ShowOnWebSite == true
&& product.AvailableDate <= DateTime.Today
&& ( product.DiscontinuationDate == null || product.DiscontinuationDate >= DateTime.Today )
select product.ManufacturerID.ToString() );
var activeArtists = from artist in Master.DataContext.ContactSet
where activeProduct.Contains(artist.ID.ToString())
select artist;
NumberOfArtists = activeArtists.Count();
artistsRepeater.DataSource = activeArtists;
artistsRepeater.DataBind();
[Больше деталей] ManufacturerID является nullable GUID, по-видимому...
По некоторым причинам класс ContactSet не содержит ссылки на продукты, я предполагаю, что должен буду сделать запрос соединения, никакие подсказки здесь.
Наконец-то мне удалось кодировать что-то безобразное, но это на самом деле работает! (LOL)
var activeProduct =(from product in Master.DataContext.ProductSet
where product.Active == true
&& product.ShowOnWebSite == true
&& product.AvailableDate <= DateTime.Today
&& ( product.DiscontinuationDate == null || product.DiscontinuationDate >= DateTime.Today )
select product.ManufacturerID ).Distinct();
var artists = from artist in Master.DataContext.ContactSet
select artist;
List<Evolution.API.Contact> activeArtists = new List<Evolution.API.Contact>();
foreach (var artist in artists)
{
foreach(var product in activeProduct)
{
if (product.HasValue && product.Value == artist.ID)
activeArtists.Add(artist);
}
}
NumberOfArtists = activeArtists.Count();
artistsRepeater.DataSource = activeArtists;
artistsRepeater.DataBind();
Что, если вы поменяете заявление (непроверенные)?
where activeProducts.Contains(member.ID)
Как насчет этого ...
var activeProducts = (
from products in db.ProductSet
where product.Active == true
select product.ManufacturerID);
var activeMembers = (
from member in db.ContactSet
where activeProducts.Contains(member.ID.ToString()));
Вы можете сделать это в одном запросе:
var q = from member in db.ContactSet
where member.Products.Any(p => p.IsActive)
select member;
Попробуйте , где ActiveProducts.contains (Member.id)
.
Редактировать : Вы пробовали его без каких-либо ToString
S?
Нет, @dynamic не получит вам никаких преимуществ в память / кодовой размер
-121--3450549- Метод вспомогательного или расширения будет работать нормально при запросе от объектов в памяти. Но против базы данных SQL ваш код LINQ будет скомпилирован в дерево выражения, проанализированным и переведенным в команду SQL. Эта функциональность не имеет концепции пользовательских методов расширения или способов других объектов, таких как .Contains (...)
.
Это может быть легко реализовано в стандартные функции Linq-to-SQL Microsoft, хотя и Microsoft. Но до тех пор, пока они не хотят, мы беспомощны, пока это не функциональность с открытым исходным кодом.
Все, что вы можете сделать, это создать свой собственный QueryProvider, который идет против базы данных SQL. Но это будет тяжело, и это было бы только для того, чтобы только один в
в нем отсутствую.
Однако, если вы действительно хотите пойти на этот маршрут, повеселитесь: LINQ: Создание серии IQueryable поставщика
Вместо этого:
var activeMembers = (
from member in db.ContactSet
where member.ID.ToString().Contains(activeProducts));
Попробуйте это:
var activeMembers = (
from member in db.ContactSet
where activeProducts.Contains(member.ID));
Попробуйте решение, размещенное CoLin Mirk по адресу: http://social.msdn.microsoft.com/forums/en-us/adodotnetentityframework/thrad/095745fe-dcf0-4142- B684-B7E4A1AB59F0 / . Это сработало для меня.