我有两个实体-客户和工作。客户与0到许多工作相关联。
客户端如下:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using JobsLedger.INTERFACES;
namespace JobsLedger.DATA.ENTITIES
{
#nullable enable
public class Client : IEntityBase, IAuditedEntityBase
{
public Client()
{
ClientNotes = new List<Note>();
Jobs = new List<Job>();
}
[Key]
public int Id { get; set; }
public string ClientNo { get; set; } = default!;
public bool Company { get; set; }
public string? CompanyName { get; set; }
public string? Abn { get; set; }
public bool IsWarrantyCompany { set; get; }
public bool RequiresPartsPayment { set; get; }
public string? ClientFirstName { get; set; }
public string ClientLastName { get; set; } = default!;
public string? Email { get; set; }
public string? MobilePhone { get; set; }
public string? Phone { get; set; }
public string? Address1 { get; set; }
public string? Address2 { get; set; }
public string? BankName { get; set; }
public string? BankBSB { get; set; }
public string? BankAccount { get; set; }
public bool Active { get; set; }
public DateTime? DateDeActivated { get; set; }
public bool Activity { get; set; }
// One warranty company client to a job.
public int? WarrantyCompanyId { get; set; }
public virtual Job? WarrantyCompany { get; set; }
// One suburb to a client.
public int? SuburbId { get; set; }
public virtual Suburb? Suburb { get; set; }
// If its a warranty company then we simply link it one to one to the brand id.
public virtual Brand? Brand { get; set; }
// Multiple notes for each client.
public virtual ICollection<Note> ClientNotes { get; set; }
// Multiple jobs for each client.
public virtual ICollection<Job> Jobs { get; set; }
public virtual ICollection<Job> WarrantyCompanyJobs { get; } = default!;
}
#nullable disable
}
工作如下:
using System.Collections.Generic;
using JobsLedger.INTERFACES;
namespace JobsLedger.DATA.ENTITIES
{
public class Job : IEntityBase, IAuditedEntityBase
{
public Job()
{
JobNotes = new List<Note>();
Visits = new List<Visit>();
}
public string? JobNo { get; set; }
public string? AgentJobNo { get; set; }
public int ClientId { get; set; } = default!;
public virtual Client Client { get; set; } = default!;
public int? BrandId { get; set; }
public virtual Brand? Brand { get; set; }
public int? TypeId { get; set; }
public virtual JobType? Type { get; set; }
public int? StatusId { get; set; }
public virtual Status? Status { get; set; }
public int? WarrantyCompanyId { get; set; }
public virtual Client? WarrantyCompany { get; set; }
public string? Model { get; set; }
public string? Serial { get; set; }
public string? ProblemDetails { get; set; }
public string? SolutionDetails { get; set; }
public virtual ICollection<Note> JobNotes { get; set; }
public virtual ICollection<Visit> Visits { get; }
public int Id { get; set; }
}
#nullable disable
}
此Linq Join有效,并且我返回ClientIndexDtos的列表。
public IQueryable<ClientIndexDto> GetClients()
{
var result = this._context.Clients.Join(this._context.Jobs, c => c.Id, j => j.Id, (c, j) =>
new ClientIndexDto
{
Id = c.Id,
ClientNo = c.ClientNo,
Active = c.Active,
ClientFirstName = c.ClientFirstName,
ClientLastName = c.ClientLastName,
Company = c.Company,
CompanyName = c.CompanyName,
MobilePhone = c.MobilePhone,
IsWarrantyCompany = c.IsWarrantyCompany,
//JobsCount = j.Count().ToString(CultureInfo.CurrentCulture)
});
return result;
}
但是..我想要每个客户的工作数量(如果有)...所以我问了this question on SO,建议这样做:
public IQueryable<ClientIndexDto> GetClients()
{
var result = this._context.Clients.GroupJoin(this._context.Jobs, c => c.Id, j => j.Id, (c, j) =>
new ClientIndexDto
{
Id = c.Id,
ClientNo = c.ClientNo,
Active = c.Active,
ClientFirstName = c.ClientFirstName,
ClientLastName = c.ClientLastName,
Company = c.Company,
CompanyName = c.CompanyName,
MobilePhone = c.MobilePhone,
IsWarrantyCompany = c.IsWarrantyCompany,
JobsCount = j.Count().ToString(CultureInfo.CurrentCulture)
});
return result;
}
虽然它适用于联接版本,但在使用groupJoin运行时出现以下错误。
The LINQ expression 'DbSet<Client>()
.GroupJoin(
inner: DbSet<Job>(),
outerKeySelector: c => c.Id,
innerKeySelector: j => j.Id,
resultSelector: (c, j) => new ClientIndexDto{
Id = c.Id,
ClientNo = c.ClientNo,
Active = c.Active,
ClientFirstName = c.ClientFirstName,
ClientLastName = c.ClientLastName,
Company = c.Company,
CompanyName = c.CompanyName,
MobilePhone = c.MobilePhone,
IsWarrantyCompany = c.IsWarrantyCompany
}
)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
[我注意到,URL-https://go.microsoft.com/fwlink/?linkid=2101038讨论了客户端-服务器的评估...好吧,我自然希望在数据库中进行此评估,但是对于为什么一个(Join)畅通而另一个(GroupJoin)失败的原因感到困惑。] >
有人可以回答为什么它先不起作用,然后告诉我需要做什么来修复它。除了需要知道每个客户端上有多少工作外,我将使用Join。 GroupJoin将给我,如果我能使它正常工作...
我知道我希望在数据库端执行它,即获取一个IQueryable等,这样它就不会将多余的记录拖回客户端。”>
任何帮助表示赞赏。
我有两个实体-客户和工作。客户有0到许多与之关联的工作。客户端如下:使用系统;使用System.Collections.Generic;使用System.ComponentModel ....
您必须了解实现IQueryable
的对象与实现IEnumerable
的对象之间的区别。
IEnumerable
代表相似项目的序列。您可以获取序列的第一个元素,一旦获得了该元素,就可以获取下一个元素。