【问题标题】:LINQ join issue, returns all null valueLINQ 连接问题,返回所有空值
【发布时间】:2013-01-19 23:01:27
【问题描述】:

我是EFLINQ 的新手,我面临一个奇怪的问题。当我在select new 块中检查空值时,子表中的所有值都为空。下面是LINQ 查询。

我的 Linq 代码

var linqResult = from pd in entities.tblpackagedetails
         join ps in entities.tblpackageselecteds
         on pd.PackageDetailsID equals ps.PackageDetailsID 
         into tabJoin
         from tj in tabJoin.Where(ps => ps.UserID == userID 
         && ps.IsActive == true).DefaultIfEmpty()
         select new
         {
             IsComplete = (tj == null) ? false : tj.IsComplete,
             IsActive = (tj == null) ? false : tj.IsActive,
             UserID = (tj == null) ? 0 : tj.UserID,
             IsMandatory = pd.IsMandatory,
             PackageSelectedID = (tj == null) ? 0 : tj.PackageSelectedID,
             IsSelected = (tj == null ? false : tj.IsSelected),
             pd.Amount,
             pd.Code,
             pd.Description,
             pd.Points,
             pd.PackageDetailsID
         };

        foreach (var result in linqResult)
        {
            packagesSelected.Add(new PackageDetailDataModel()
            {
                Amount = result.Amount,
                Code = result.Code,
                Description = result.Description,
                IsComplete = result.IsComplete,
                IsMandatory = result.IsMandatory,
                PackageDetailsID = result.PackageDetailsID,
                PackageSelectedID = result.PackageSelectedID,
                Points = result.Points,
                IsActive = result.IsActive,
                UserID = result.UserID,
                IsSelected = result.IsSelected
            });
        }

Visualizer 生成的 SQL

    SELECT
    `Extent1`.`PackageDetailsID`, 
    `Extent2`.`IsComplete`, 
    `Extent2`.`IsActive`, 
    `Extent2`.`UserID`, 
    `Extent1`.`IsMandatory`, 
    `Extent2`.`PackageSelectedID`, 
    `Extent2`.`IsSelected`, 
    `Extent1`.`Amount`, 
    `Extent1`.`Code`, 
    `Extent1`.`Description`, 
    `Extent1`.`Points`
    FROM `tblpackagedetails` AS `Extent1` 
    LEFT OUTER JOIN `tblpackageselected` AS `Extent2` 
    ON (`Extent1`.`PackageDetailsID` = `Extent2`.`PackageDetailsID`) 
    AND ((`Extent2`.`UserID` = @linq_0) AND (1 = `Extent2`.`IsActive`))

当我在 MySQL 工作台上运行 sql 时,我得到了以下输出(用用户 ID 替换 @linq_0)。

我的父表结构

子表结构

我想要的输出

但是IsCompleteIsActiveUserIDPackageSelectedIDIsSelected 的值在select new 块中作为结果条件检查分配为false 或0。

如果我删除空检查,我会得到前 3 行的值,并且在第四次迭代中我得到低于异常。 The cast to value type 'Boolean' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type

请帮忙... :(

工作代码块

        packagesSelected = new List<PackageDetailDataModel>();
    var linqResult = from pd in entities.tblpackagedetails
                     join ps in entities.tblpackageselecteds
                     on pd.PackageDetailsID equals ps.PackageDetailsID
                     into tabJoin
                     from tj in tabJoin.Where(ps => ps.UserID == userID
                     && ps.IsActive == true).DefaultIfEmpty()
                     select new
                     {
                         IsComplete = (bool?)tj.IsComplete,
                         IsActive = (bool?)tj.IsActive,
                         UserID = (int?)tj.UserID,
                         IsMandatory = pd.IsMandatory,
                         PackageSelectedID = (int?)tj.PackageSelectedID,
                         IsSelected = (bool?)tj.IsSelected,
                         pd.Amount,
                         pd.Code,
                         pd.Description,
                         pd.Points,
                         pd.PackageDetailsID
                     };

    foreach (var result in linqResult)
    {
        packagesSelected.Add(new PackageDetailDataModel()
        {
            Amount = result.Amount,
            Code = result.Code,
            Description = result.Description,
            IsComplete = (result.IsComplete ?? false),
            IsMandatory = result.IsMandatory,
            PackageDetailsID = result.PackageDetailsID,
            PackageSelectedID = (result.PackageSelectedID ?? 0),
            Points = result.Points,
            IsActive = (result.IsActive ?? false),
            UserID = (result.UserID ?? 0),
            IsSelected = (result.IsSelected ?? false)
        });
    }

感谢2Kay :)

【问题讨论】:

    标签: linq entity-framework c#-4.0


    【解决方案1】:

    tjnull 时,EF 将tj 的所有属性视为null。没关系,但是当 EF 试图将它们具体化为值类型时,它会失败。所以解决方案是使用可空类型..

    试试这个查询:

    var linqResult = from pd in entities.tblpackagedetails
         join ps in entities.tblpackageselecteds
         on pd.PackageDetailsID equals ps.PackageDetailsID 
         into tabJoin
         from tj in tabJoin.Where(ps => ps.UserID == userID 
         && ps.IsActive == true).DefaultIfEmpty()
         select new
         {
             IsComplete = (bool?) tj.IsComplete,
             IsActive = (bool?) tj.IsActive,
             UserID = (int?) tj.UserID,
             IsMandatory = pd.IsMandatory,
             PackageSelectedID = (int?) tj.PackageSelectedID,
             IsSelected = (bool?) tj.IsSelected,
             pd.Amount,
             pd.Code,
             pd.Description,
             pd.Points,
             pd.PackageDetailsID
         };
    

    【讨论】:

    • 这没有帮助,有异常声明The cast to value type 'Boolean' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.任何其他建议???
    • 谢谢,它的工作。仅供参考,我不得不修改我的foreach 块来处理空值。我将发布该块,这也将对其他人有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    • 2013-05-04
    • 1970-01-01
    • 2012-11-30
    相关资源
    最近更新 更多