有人可以向我解释一下这里出了什么问题吗?我正在使用 Linq to Sql 创建一个非常讨厌的查询。
我遇到的问题是我需要在某些表上进行左连接
(使用 DefaultIfEmpty
)我需要从
DefaultIfEmpty(new SomeObject(){...})
以便我稍后可以再次对其进行连接。
我的问题是 DefaultIfEmpty 总是返回 null。所以我检查了一些虚拟数据作为 POC,它有效
示例
我似乎找不到用于获取下面示例代码的链接,我只是对其进行了一些更改以向 OrderConfirmed
添加额外的连接,因此在运行它时,它的工作原理如下预计。
List<Book> bookList = new List<Book>
{
new Book{BookID=1, BookNm="DevCurry.com Developer Tips"},
new Book{BookID=2, BookNm=".NET and COM for Newbies"},
new Book{BookID=3, BookNm="51 jQuery ASP.NET Recipes"},
new Book{BookID=4, BookNm="Motivational Gurus"},
new Book{BookID=5, BookNm="Spiritual Gurus"}
};
List<Order> bookOrders = new List<Order>
{
new Order{OrderID=1, BookID=1, PaymentMode="Cheque"},
new Order{OrderID=2, BookID=5, PaymentMode="Credit"},
new Order{OrderID=3, BookID=1, PaymentMode="Cash"},
new Order{OrderID=4, BookID=3, PaymentMode="Cheque"},
new Order{OrderID=5, BookID=5, PaymentMode="Cheque"},
new Order{OrderID=6, BookID=4, PaymentMode="Cash"}
};
List<OrderConfirmed> orderConfirmed = new List<OrderConfirmed>();
var orderForBooks = from bl in bookList
join ordr in bookOrders on bl.BookID equals ordr.BookID into a
from ordr in a.DefaultIfEmpty(new Order {BookID = -1, OrderID = 12, PaymentMode = "Cash Test" }) // return default value
join confirmed in orderConfirmed on ordr.OrderID equals confirmed.OrderID into c
from confirmed in c.DefaultIfEmpty(new OrderConfirmed() { OrderID = 12, Description = "Is this working"}) // no values in orderconfirmed so returning new object
select new
{
bl,
ordr,
confirmed
};
因此,知道我正在尝试执行的操作应该有效,在我的实际代码中,DefaultIfEmpty
始终为 null。我说这应该有效吗?
也许需要注意的是我正在使用 EFCORE
var formData =
await (from ccf in this.context.Set<BureauCountryCustomForm>()
join ccfa in this.context.Set<EmployeeCustomFormAttributeHeader>() on ccf.BureauCountryFormId equals ccfa.BureauCountryFormId into ccfaJoin
from ccfa in ccfaJoin.DefaultIfEmpty(new EmployeeCustomFormAttributeHeader()
{
HeaderId = -1,
BureauCountryFormId = 3,
CompanyFormId = -1,
EmployeeId = 1
})
join cca in this.context.Set<BureauCountryCustomFormAttribute>() on ccf.BureauCountryFormId equals cca.BureauCountryFormId
join edv in this.context.Set<EmployeeCustomFormValue>() on
new { AttributeId = (int?)cca.BureauCountryFormAttributeId, HeaderId = (int?)ccfa.HeaderId } equals
new { AttributeId = (int?)edv.FormAttributeId, HeaderId = (int?)edv.HeaderId } into edvJoin
from edv in edvJoin.DefaultIfEmpty(new EmployeeCustomFormValue()
{
HeaderId = -1,
FormAttributeId = -1
})
where ccf.CountryId == countryId && ccf.EmployeeLevel == true && ccfa.EmployeeId == employeeId
select new { ccf, ccfa, cca, edv }).GroupBy(g => new { g.ccf.BureauCountryFormId, g.ccfa.HeaderId })
.Select(
_ => new CustomFormData
{
Keys = new[] { _.Key.BureauCountryFormId, _.Key.HeaderId },
FormName = _.First().ccf.FormName,
EffectiveDate = _.First().ccfa.EffectiveDate,
FormDataFields = _.Select(
f => new CustomFormDataField
{
AttributeId = f.cca.BureauCountryFormAttributeId,
FieldLabel = f.cca.FieldLabel,
IsMandatory = f.cca.IsMandatory,
FieldValue = f.edv.FieldValue,
ControlTypeId = (long)f.cca.ControlTypeId,
DropdownValues = f.cca.DropdownValues,
Order = f.cca.AttOrderNo,
ValidationRule = f.cca.ValidationRule,
ValidationExpression = f.cca.ValidationExpression
}).ToList()
}).ToListAsync();
最佳答案
问题出在:
from ccfa in ccfaJoin.DefaultIfEmpty(new EmployeeCustomFormAttributeHeader())
这样的查询构造只能用于数据库集或查询等集合,而不是 DefaultIfEmpty,但它是 IEnumerable,但 EF Core 将其视为单个值(如果没有匹配,则在 sql 查询结果中实际上为 null),无论它在哪里使用过。
您应该将其更改为:
let ccfa = ccfaJoin.DefaultIfEmpty(new EmployeeCustomFormAttributeHeader())
它应该按预期工作。
关于c# - linq 语句的 DefaultIfEmpty 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49372314/