ServiceStack ORMLite - 无法推断关系(因为 DTO 名称?)
ServiceStack ORMLite - Can't Infer Relationship (because of DTO name?)
我正在为每次访问客户时执行多项服务的服务业务建模。我有一个访问 table、一个服务 table 和一个 link table、VisitService。我在我的服务中使用此请求 DTO 来获取访问服务列表:
[Route("/visits/{visitid}/services", Verbs = "GET")]
public class ServicesAtVisit : QueryBase<VisitService, ServiceAtVisit>, IJoin<VisitService, My.Namespace.Service> {
public int VisitId { get; set; }
}
ServiceAtVisit 是我要投影到的自定义 DTO。
因为我的一个 DTO 是 class,名字很不幸 "Service",我必须在 IJoin 中完全限定它,否则它与 ServiceStack.Service 不明确.现在,当我到达路线时,出现错误 "Could not infer relationship between VisitService and Service"。
有趣的是,我已经将此与其他多对多关系一起使用(Client.AssignedStaffMembers,StaffMember.AssignedClients tables Client -> ClientStaffMember -> StaffMember),我看不出有什么不同。
问题是我的 DTO 的名称以及我必须完全限定它的事实吗?
访问:
[Route("/visits", Verbs = "POST")]
public partial class Visit {
[AutoIncrement]
public long Id { get; set; }
public int ServiceRequestId { get; set; }
public string TimeOfDay { get; set; }
public DateTime Date { get; set; }
public TimeSpan? PreferredStartTime { get; set; }
public TimeSpan? PreferredEndTime { get; set; }
public bool IsFirstVisit { get; set; }
public bool IsLastVisit { get; set; }
public bool IncursWeekendFee { get; set; }
public bool WaiveWeekendFee { get; set; }
public bool IncursHolidayFee { get; set; }
public bool WaiveHolidayFee { get; set; }
public bool IncursLastMinuteSchedulingFee { get; set; }
public bool WaiveLastMinuteSchedulingFee { get; set; }
public bool IncursLastMinuteCancellationFee { get; set; }
public bool WaiveLastMinuteCancellationFee { get; set; }
public int? StaffMemberId { get; set; }
public string Notes { get; set; }
public bool IsCancelled { get; set; }
public DateTime? CheckInDateTime { get; set; }
public int? CheckInStaffMemberId { get; set; }
public DateTime? CheckOutDateTime { get; set; }
public int? CheckOutStaffMemberId { get; set; }
[Ignore]
public ServiceRequest ServiceRequest { get; set; }
[Ignore]
public StaffMember StaffMember { get; set; }
[Ignore]
public List<ServiceAtVisit> ServicesAtVisit { get; set; }
}
访问服务:
public partial class VisitService {
// Workaround for composite key limitation
public string Id {
get {
return this.VisitId.ToString() + "|" + this.ServiceId.ToString();
}
}
public long VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
[Ignore]
public Visit Visit { get; set; }
[Ignore]
public Service Service { get; set; }
}
服务:
public partial class Service {
[AutoIncrement]
public int Id { get; set; }
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
[Ignore]
public ServiceType ServiceType { get; set; }
[Ignore]
public ServicePrice CurrentPrice { get; set; }
}
将结果投影到 ServiceAtVisit:
public partial class ServiceAtVisit {
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
public int VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
}
我刚刚尝试使用您在自定义 MyNamespace
下提供的所有类型创建自动查询服务,并且它按预期工作(在最新的 ServiceStack 中),即:
服务定义:
namespace MyNamespace
{
[Route("/visits/{VisitId}/services", Verbs = "GET")]
public class ServicesAtVisit : QueryBase<VisitService, ServiceAtVisit>,
IJoin<VisitService, Service>
{
public int VisitId { get; set; }
}
public partial class ServiceAtVisit
{
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
public int VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
}
}
类型定义:
namespace MyNamespace
{
[Route("/visits", Verbs = "POST")]
public partial class Visit
{
[AutoIncrement]
public long Id { get; set; }
public int ServiceRequestId { get; set; }
public string TimeOfDay { get; set; }
public DateTime Date { get; set; }
public TimeSpan? PreferredStartTime { get; set; }
public TimeSpan? PreferredEndTime { get; set; }
public bool IsFirstVisit { get; set; }
public bool IsLastVisit { get; set; }
public bool IncursWeekendFee { get; set; }
public bool WaiveWeekendFee { get; set; }
public bool IncursHolidayFee { get; set; }
public bool WaiveHolidayFee { get; set; }
public bool IncursLastMinuteSchedulingFee { get; set; }
public bool WaiveLastMinuteSchedulingFee { get; set; }
public bool IncursLastMinuteCancellationFee { get; set; }
public bool WaiveLastMinuteCancellationFee { get; set; }
public int? StaffMemberId { get; set; }
public string Notes { get; set; }
public bool IsCancelled { get; set; }
public DateTime? CheckInDateTime { get; set; }
public int? CheckInStaffMemberId { get; set; }
public DateTime? CheckOutDateTime { get; set; }
public int? CheckOutStaffMemberId { get; set; }
//[Ignore]
//public ServiceRequest ServiceRequest { get; set; }
//[Ignore]
//public StaffMember StaffMember { get; set; }
[Ignore]
public List<ServiceAtVisit> ServicesAtVisit { get; set; }
}
public partial class VisitService
{
// Workaround for composite key limitation
public string Id
{
get
{
return this.VisitId.ToString() + "|" + this.ServiceId.ToString();
}
}
public long VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
[Ignore]
public Visit Visit { get; set; }
[Ignore]
public Service Service { get; set; }
}
public partial class Service
{
[AutoIncrement]
public int Id { get; set; }
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
//[Ignore]
//public ServiceType ServiceType { get; set; }
//[Ignore]
//public ServicePrice CurrentPrice { get; set; }
}
}
测试数据:
using (var db = container.Resolve<IDbConnectionFactory>().Open())
{
db.DropAndCreateTable<MyNamespace.Visit>();
db.DropAndCreateTable<MyNamespace.VisitService>();
db.DropAndCreateTable<MyNamespace.Service>();
var visitId = db.Insert(new MyNamespace.Visit {
Date = DateTime.UtcNow, Notes = "Notes"}, selectIdentity: true);
var serviceId = (int)db.Insert(new MyNamespace.Service {
ServiceTypeId = 1, Name = "Name"}, selectIdentity:true);
db.Insert(new MyNamespace.VisitService {
VisitId = visitId, ServiceId = serviceId, Quantity = 1});
}
服务结果:
http://localhost:{port}/visits/1/services.json
JSON 响应:
{
offset: 0,
total: 1,
results: [{
serviceTypeId: 1,
name: "Name",
displayOrder: 0,
isHourly: false,
isMonthly: false,
visitId: 1,
serviceId: 1,
quantity: 1,
feeIsWaived: false
}]
}
我正在为每次访问客户时执行多项服务的服务业务建模。我有一个访问 table、一个服务 table 和一个 link table、VisitService。我在我的服务中使用此请求 DTO 来获取访问服务列表:
[Route("/visits/{visitid}/services", Verbs = "GET")]
public class ServicesAtVisit : QueryBase<VisitService, ServiceAtVisit>, IJoin<VisitService, My.Namespace.Service> {
public int VisitId { get; set; }
}
ServiceAtVisit 是我要投影到的自定义 DTO。
因为我的一个 DTO 是 class,名字很不幸 "Service",我必须在 IJoin 中完全限定它,否则它与 ServiceStack.Service 不明确.现在,当我到达路线时,出现错误 "Could not infer relationship between VisitService and Service"。
有趣的是,我已经将此与其他多对多关系一起使用(Client.AssignedStaffMembers,StaffMember.AssignedClients tables Client -> ClientStaffMember -> StaffMember),我看不出有什么不同。
问题是我的 DTO 的名称以及我必须完全限定它的事实吗?
访问:
[Route("/visits", Verbs = "POST")]
public partial class Visit {
[AutoIncrement]
public long Id { get; set; }
public int ServiceRequestId { get; set; }
public string TimeOfDay { get; set; }
public DateTime Date { get; set; }
public TimeSpan? PreferredStartTime { get; set; }
public TimeSpan? PreferredEndTime { get; set; }
public bool IsFirstVisit { get; set; }
public bool IsLastVisit { get; set; }
public bool IncursWeekendFee { get; set; }
public bool WaiveWeekendFee { get; set; }
public bool IncursHolidayFee { get; set; }
public bool WaiveHolidayFee { get; set; }
public bool IncursLastMinuteSchedulingFee { get; set; }
public bool WaiveLastMinuteSchedulingFee { get; set; }
public bool IncursLastMinuteCancellationFee { get; set; }
public bool WaiveLastMinuteCancellationFee { get; set; }
public int? StaffMemberId { get; set; }
public string Notes { get; set; }
public bool IsCancelled { get; set; }
public DateTime? CheckInDateTime { get; set; }
public int? CheckInStaffMemberId { get; set; }
public DateTime? CheckOutDateTime { get; set; }
public int? CheckOutStaffMemberId { get; set; }
[Ignore]
public ServiceRequest ServiceRequest { get; set; }
[Ignore]
public StaffMember StaffMember { get; set; }
[Ignore]
public List<ServiceAtVisit> ServicesAtVisit { get; set; }
}
访问服务:
public partial class VisitService {
// Workaround for composite key limitation
public string Id {
get {
return this.VisitId.ToString() + "|" + this.ServiceId.ToString();
}
}
public long VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
[Ignore]
public Visit Visit { get; set; }
[Ignore]
public Service Service { get; set; }
}
服务:
public partial class Service {
[AutoIncrement]
public int Id { get; set; }
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
[Ignore]
public ServiceType ServiceType { get; set; }
[Ignore]
public ServicePrice CurrentPrice { get; set; }
}
将结果投影到 ServiceAtVisit:
public partial class ServiceAtVisit {
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
public int VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
}
我刚刚尝试使用您在自定义 MyNamespace
下提供的所有类型创建自动查询服务,并且它按预期工作(在最新的 ServiceStack 中),即:
服务定义:
namespace MyNamespace
{
[Route("/visits/{VisitId}/services", Verbs = "GET")]
public class ServicesAtVisit : QueryBase<VisitService, ServiceAtVisit>,
IJoin<VisitService, Service>
{
public int VisitId { get; set; }
}
public partial class ServiceAtVisit
{
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
public int VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
}
}
类型定义:
namespace MyNamespace
{
[Route("/visits", Verbs = "POST")]
public partial class Visit
{
[AutoIncrement]
public long Id { get; set; }
public int ServiceRequestId { get; set; }
public string TimeOfDay { get; set; }
public DateTime Date { get; set; }
public TimeSpan? PreferredStartTime { get; set; }
public TimeSpan? PreferredEndTime { get; set; }
public bool IsFirstVisit { get; set; }
public bool IsLastVisit { get; set; }
public bool IncursWeekendFee { get; set; }
public bool WaiveWeekendFee { get; set; }
public bool IncursHolidayFee { get; set; }
public bool WaiveHolidayFee { get; set; }
public bool IncursLastMinuteSchedulingFee { get; set; }
public bool WaiveLastMinuteSchedulingFee { get; set; }
public bool IncursLastMinuteCancellationFee { get; set; }
public bool WaiveLastMinuteCancellationFee { get; set; }
public int? StaffMemberId { get; set; }
public string Notes { get; set; }
public bool IsCancelled { get; set; }
public DateTime? CheckInDateTime { get; set; }
public int? CheckInStaffMemberId { get; set; }
public DateTime? CheckOutDateTime { get; set; }
public int? CheckOutStaffMemberId { get; set; }
//[Ignore]
//public ServiceRequest ServiceRequest { get; set; }
//[Ignore]
//public StaffMember StaffMember { get; set; }
[Ignore]
public List<ServiceAtVisit> ServicesAtVisit { get; set; }
}
public partial class VisitService
{
// Workaround for composite key limitation
public string Id
{
get
{
return this.VisitId.ToString() + "|" + this.ServiceId.ToString();
}
}
public long VisitId { get; set; }
public int ServiceId { get; set; }
public int Quantity { get; set; }
public bool FeeIsWaived { get; set; }
[Ignore]
public Visit Visit { get; set; }
[Ignore]
public Service Service { get; set; }
}
public partial class Service
{
[AutoIncrement]
public int Id { get; set; }
public int ServiceTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool IsHourly { get; set; }
public bool IsMonthly { get; set; }
//[Ignore]
//public ServiceType ServiceType { get; set; }
//[Ignore]
//public ServicePrice CurrentPrice { get; set; }
}
}
测试数据:
using (var db = container.Resolve<IDbConnectionFactory>().Open())
{
db.DropAndCreateTable<MyNamespace.Visit>();
db.DropAndCreateTable<MyNamespace.VisitService>();
db.DropAndCreateTable<MyNamespace.Service>();
var visitId = db.Insert(new MyNamespace.Visit {
Date = DateTime.UtcNow, Notes = "Notes"}, selectIdentity: true);
var serviceId = (int)db.Insert(new MyNamespace.Service {
ServiceTypeId = 1, Name = "Name"}, selectIdentity:true);
db.Insert(new MyNamespace.VisitService {
VisitId = visitId, ServiceId = serviceId, Quantity = 1});
}
服务结果:
http://localhost:{port}/visits/1/services.json
JSON 响应:
{
offset: 0,
total: 1,
results: [{
serviceTypeId: 1,
name: "Name",
displayOrder: 0,
isHourly: false,
isMonthly: false,
visitId: 1,
serviceId: 1,
quantity: 1,
feeIsWaived: false
}]
}