Оказывается, что запрос LINQ не эквивалентен запросу SQL, публикуемую в связи с использованием products
переменная запроса (не показана в сообщении), которая приводит к включению одной из таблиц ссылок many-to-many
в два раза, что дает больше записей.
Один из способов устранить проблему - заменить products
на db.Products
и применить те же фильтры, что и к переменным запроса, которые вы пытались повторно использовать.
Но если вы хотите использовать переменные запроса, то здесь правильный способ сделать это:
// Eliminate the need of DbFunctions.TruncateTime(dt) inside the queries
dt = dt.Date;
// Queries
var productFamilys = (
from tt in db.TestTypes
join ttpf in db.TestTypeProductFamilys on tt.TestTypeID equals ttpf.TestTypeID
join pf in db.ProductFamilys on ttpf.ProductFamilyID equals pf.ProductFamilyID
where tt.TestTypeID == TestTypeID
where DbFunctions.TruncateTime(pf.StartDate) <= dt
where DbFunctions.TruncateTime(pf.EndDate) > dt
select pf
);
var productFamilyProducts = (
from pf in productFamilys
join pfp in db.ProductFamilyProducts on pf.ProductFamilyID equals pfp.ProductFamilyID
join p in db.Products on pfp.ProductID equals p.ProductID
where DbFunctions.TruncateTime(p.StartDate) <= dt
where DbFunctions.TruncateTime(p.EndDate) > dt
select new { Family = pf, Product = p }
);
var products = (
from pfp in productFamilyProducts
select pfp.Product
);
var productFamilyProductVMs = (
from pfp in productFamilyProducts
orderby pfp.Product.ProductID, pfp.Family.ProductFamilyID
select new ProductFamilyProductVM
{
ProductFamilyID = pfp.Family.ProductFamilyID,
ProductID = pfp.Product.ProductID,
ProdDesc = pfp.Product.Description
}
);
// Results
trvm.ProductFamilys = productFamilys.ToList();
trvm.Products = products.ToList();
trvm.ProductFamilyProductVMs = productFamilyProductVMs.ToList();
Теперь SQL для последнего запроса (один в вопросе) выглядит следующим образом
SELECT
[Project1].[ProductFamilyID] AS [ProductFamilyID],
[Project1].[ProductID] AS [ProductID],
[Project1].[Description] AS [Description]
FROM (SELECT
[Extent2].[ProductFamilyID] AS [ProductFamilyID],
[Extent4].[ProductID] AS [ProductID],
[Extent4].[Description] AS [Description]
FROM [dbo].[TestTypeProductFamilies] AS [Extent1]
INNER JOIN [dbo].[ProductFamilies] AS [Extent2] ON [Extent1].[ProductFamilyID] = [Extent2].[ProductFamilyID]
INNER JOIN [dbo].[ProductFamilyProducts] AS [Extent3] ON [Extent2].[ProductFamilyID] = [Extent3].[ProductFamilyID]
INNER JOIN [dbo].[Products] AS [Extent4] ON [Extent3].[ProductID] = [Extent4].[ProductID]
WHERE ([Extent1].[TestTypeID] = @p__linq__0) AND ((convert (datetime2, convert(varchar(255), [Extent2].[StartDate], 102) , 102)) <= @p__linq__1) AND ((convert (datetime2, convert(varchar(255), [Extent2].[EndDate], 102) , 102)) > @p__linq__2) AND ((convert (datetime2, convert(varchar(255), [Extent4].[StartDate], 102) , 102)) <= @p__linq__3) AND ((convert (datetime2, convert(varchar(255), [Extent4].[EndDate], 102) , 102)) > @p__linq__4)
) AS [Project1]
ORDER BY [Project1].[ProductID] ASC, [Project1].[ProductFamilyID] ASC
т. Е. Очень похож на образец SQL-запроса и должен давать одинаковые результаты.
Учитываются ли представления базы данных или просто таблицы? Таблицы без ПК? –
просто столов. первичный ключ находится в таблицах – jubi
Исправьте предложение 'order by', затем измените код следующим образом:' var query = (...); '(без' ToList() 'call), затем' var sql = query. Нанизывать(); trvm.ProductFamilyProductVMs = query.ToList(); ', помещает точку останова и видит, что переменная' sql' содержит текст запроса SQL. Если да, откройте его с помощью Text Visualizer, скопируйте и вставьте его в вопрос. –