我正在尝试按照本教程https://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-use-existing-sql-database/创建一个项目的移动后端。我试图获取tblField中的所有数据。这是我收到的错误消息
{"message":"The query specified in the URI is not valid. Could not find a property named 'Id' on type
'cimsmobileService.DataObjects.DTOtblField'.","exceptionMessage":"
Could not find a property named 'Id' on type
'cimsmobileService.DataObjects.DTOtblField'.","exceptionType":"Microsoft.Data.OData.ODataException","stackTrace":" at
Microsoft.Data.OData.Query.SyntacticAst.SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(PathSegmentToken tokenIn, IEdmModel model, IEdmEntityType entityType)\r\n at
Microsoft.Data.OData.Query.SyntacticAst.SelectPropertyVisitor.ProcessTokenAsPath(NonSystemToken tokenIn)\r\n at
Microsoft.Data.OData.Query.SyntacticAst.SelectPropertyVisitor.Visit(NonSystemToken tokenIn)\r\n at
Microsoft.Data.OData.Query.SyntacticAst.NonSystemToken.Accept(IPathSegmentTokenVisitor visitor)\r\n at
Microsoft.Data.OData.Query.SyntacticAst.SelectBinder.Bind(SelectToken tokenIn)\r\n at
Microsoft.Data.OData.Query.SelectExpandSemanticBinder.Parse(IEdmEntityType elementType, IEdmEntitySet entitySet, ExpandToken expandToken, SelectToken selectToken, ODataUriParserConfiguration configuration)\r\n at
Microsoft.Data.OData.Query.ODataUriParser.ParseSelectAndExpandImplementation(String select, String expand, IEdmEntityType elementType, IEdmEntitySet entitySet)\r\n at
Microsoft.Data.OData.Query.ODataUriParser.ParseSelectAndExpand(String select, String expand, IEdmEntityType elementType, IEdmEntitySet entitySet)\r\n at System.Web.Http.OData.Query.SelectExpandQueryOption.get_SelectExpandClause()\r\n at
System.Web.Http.OData.Query.Validators.SelectExpandQueryValidator.Validate(SelectExpandQueryOption selectExpandQueryOption, ODataValidationSettings validationSettings)\r\n at
System.Web.Http.OData.Query.SelectExpandQueryOption.Validate(ODataValidationSettings validationSettings)\r\n at
System.Web.Http.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at
System.Web.Http.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n at
System.Web.Http.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n at
System.Web.Http.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n at
System.Web.Http.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"}
在WebApiConfig类
中 public static class WebApiConfig
{
public static void Register()
{
// Use this class to set configuration options for your mobile service
ConfigOptions options = new ConfigOptions();
// Use this class to set WebAPI configuration options
HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options));
// To display errors in the browser during development, uncomment the following
// line. Comment it out again when you deploy your service for production use.
// config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
// Set default and null value handling to "Include" for Json Serializer
config.Formatters.JsonFormatter.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Include;
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include;
Database.SetInitializer(new cimsInitializer());
Mapper.Initialize(cfg =>
{
cfg.CreateMap<DTOtblField, tblField>();
cfg.CreateMap<tblField, DTOtblField>()
.ForMember(dst => dst.DTOkeyFieldID, map => map.MapFrom(x => x.Id));
});
}
}
public class cimsInitializer : ClearDatabaseSchemaIfModelChanges<cimsContext>
{
protected override void Seed(cimsContext context)
{
List<TodoItem> todoItems = new List<TodoItem>
{
new TodoItem { Id = Guid.NewGuid().ToString(), Text = "First item", Complete = false },
new TodoItem { Id = Guid.NewGuid().ToString(), Text = "Second item", Complete = false },
};
foreach (TodoItem todoItem in todoItems)
{
context.Set<TodoItem>().Add(todoItem);
}
base.Seed(context);
}
}
每当我像这样添加tblField时,它会抛出一个错误map.MapFrom(x =&gt; x.tblField.Id));
Error 2 Cannot convert lambda expression to type 'string' because it is not a delegate type C:\CIMSMobileService\cimsService\App_Start\WebApiConfig.cs 37 32 cimsService
DTOtblFieldController.cs
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.OData;
using Microsoft.WindowsAzure.Mobile.Service;
using cimsService.Models;
using cimsmobileService.DataObjects;
namespace cimsService.Controllers
{
public class DTOtblFieldController : TableController<DTOtblField>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
cims_sarm context = new cims_sarm();
DomainManager = new DTOtblFieldDomainManager(context, Request, Services);
//DomainManager = new EntityDomainManager<DTOtblField>(context, Request, Services);
}
// GET tables/DTOtblField
public IQueryable<DTOtblField> GetAllDTOtblField()
{
return Query();
}
// GET tables/DTOtblField/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<DTOtblField> GetDTOtblField(string id)
{
return Lookup(id);
}
// PATCH tables/DTOtblField/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<DTOtblField> PatchDTOtblField(string id, Delta<DTOtblField> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/DTOtblField
public async Task<IHttpActionResult> PostDTOtblField(DTOtblField item)
{
DTOtblField current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/DTOtblField/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteDTOtblField(string id)
{
return DeleteAsync(id);
}
}
}
DTOtblField.cs
using System.ComponentModel.DataAnnotations;
using Microsoft.WindowsAzure.Mobile.Service;
//-------------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by EntitiesToDTOs.v3.2 (entitiestodtos.codeplex.com).
// Timestamp: 2015/12/16 - 16:33:45
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//-------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
using System.ComponentModel.DataAnnotations.Schema;
namespace cimsmobileService.DataObjects
{
[DataContract()]
public partial class DTOtblField:EntityData
{
[NotMapped]
public Int32 keyFieldID { get; set; }
[DataMember()]
[Required]
public string DTOkeyFieldID
{
get{
return keyFieldID.ToString();
}
set{
this.keyFieldID = Int32.Parse(DTOkeyFieldID);
}
}
[DataMember()]
public String FieldText { get; set; }
[DataMember()]
public String FieldDefaultEntry { get; set; }
[DataMember()]
public String ParameterDefaultEntry { get; set; }
[DataMember()]
public String FieldType { get; set; }
[DataMember()]
public Nullable<Int32> fk_FieldGroupID { get; set; }
[DataMember()]
public String fillFlag { get; set; }
[DataMember()]
public Nullable<Boolean> isHidden { get; set; }
[DataMember()]
public Nullable<Int32> DisplayOrder { get; set; }
[DataMember()]
public Nullable<Int32> PercentageWidth { get; set; }
[DataMember()]
public Nullable<DateTime> StartEffDT { get; set; }
[DataMember()]
public Nullable<DateTime> EndEffDT { get; set; }
[DataMember()]
public String SecurityLevels { get; set; }
[DataMember()]
public List<Int32> tblEntries_keyEntryID { get; set; }
[DataMember()]
public Int32 tblFieldGroup_keyFieldGroupID { get; set; }
[DataMember()]
public List<Int32> tblFieldDetails_keyFieldDetailID { get; set; }
[DataMember()]
public List<Int32> tblLink_FieldToAsset_keyLink_FieldToAsset { get; set; }
[DataMember()]
public List<Int32> tblLink_FieldToConfiguration_keyLink_FieldToConfiguration { get; set; }
[DataMember()]
public List<Int32> tblLink_FieldToForm_keyLink_FieldToForm { get; set; }
[DataMember()]
public List<Int32> tblLink_FieldToLocation_keyLink_FieldToLocation { get; set; }
[DataMember()]
public List<Int32> tblLink_FieldToTemplate_Asset_keyLink_FieldToTemplate_Asset { get; set; }
public DTOtblField()
{
}
public DTOtblField(Int32 keyFieldID, String fieldText, String fieldDefaultEntry, String parameterDefaultEntry, String fieldType, Nullable<Int32> fk_FieldGroupID, String fillFlag, Nullable<Boolean> isHidden, Nullable<Int32> displayOrder, Nullable<Int32> percentageWidth, Nullable<DateTime> startEffDT, Nullable<DateTime> endEffDT, String securityLevels, List<Int32> tblEntries_keyEntryID, Int32 tblFieldGroup_keyFieldGroupID, List<Int32> tblFieldDetails_keyFieldDetailID, List<Int32> tblLink_FieldToAsset_keyLink_FieldToAsset, List<Int32> tblLink_FieldToConfiguration_keyLink_FieldToConfiguration, List<Int32> tblLink_FieldToForm_keyLink_FieldToForm, List<Int32> tblLink_FieldToLocation_keyLink_FieldToLocation, List<Int32> tblLink_FieldToTemplate_Asset_keyLink_FieldToTemplate_Asset)
{
this.keyFieldID = keyFieldID;
this.FieldText = fieldText;
this.FieldDefaultEntry = fieldDefaultEntry;
this.ParameterDefaultEntry = parameterDefaultEntry;
this.FieldType = fieldType;
this.fk_FieldGroupID = fk_FieldGroupID;
this.fillFlag = fillFlag;
this.isHidden = isHidden;
this.DisplayOrder = displayOrder;
this.PercentageWidth = percentageWidth;
this.StartEffDT = startEffDT;
this.EndEffDT = endEffDT;
this.SecurityLevels = securityLevels;
this.tblEntries_keyEntryID = tblEntries_keyEntryID;
this.tblFieldGroup_keyFieldGroupID = tblFieldGroup_keyFieldGroupID;
this.tblFieldDetails_keyFieldDetailID = tblFieldDetails_keyFieldDetailID;
this.tblLink_FieldToAsset_keyLink_FieldToAsset = tblLink_FieldToAsset_keyLink_FieldToAsset;
this.tblLink_FieldToConfiguration_keyLink_FieldToConfiguration = tblLink_FieldToConfiguration_keyLink_FieldToConfiguration;
this.tblLink_FieldToForm_keyLink_FieldToForm = tblLink_FieldToForm_keyLink_FieldToForm;
this.tblLink_FieldToLocation_keyLink_FieldToLocation = tblLink_FieldToLocation_keyLink_FieldToLocation;
this.tblLink_FieldToTemplate_Asset_keyLink_FieldToTemplate_Asset = tblLink_FieldToTemplate_Asset_keyLink_FieldToTemplate_Asset;
}
}
}
cim_sarm.cs
namespace cimsService.Models
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using Microsoft.WindowsAzure.Mobile.Service;
using Microsoft.WindowsAzure.Mobile.Service.Tables;
public partial class cims_sarm : DbContext
{
public cims_sarm()
: base("name=cims_sarm")
{
Database.SetInitializer<cims_sarm>(null);
}
public virtual DbSet<tblField> tblFields { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<tblField>()
.Property(e => e.FieldType)
.IsUnicode(false);
modelBuilder.Entity<tblField>()
.Property(e => e.fillFlag)
.IsFixedLength()
.IsUnicode(false);
modelBuilder.Entity<tblField>()
.Property(e => e.SecurityLevels)
.IsUnicode(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblEntries)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblFieldDetails)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblLink_FieldToAsset)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblLink_FieldToConfiguration)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblLink_FieldToForm)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblLink_FieldToLocation)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<tblField>()
.HasMany(e => e.tblLink_FieldToTemplate_Asset)
.WithRequired(e => e.tblField)
.HasForeignKey(e => e.fk_FieldID)
.WillCascadeOnDelete(false);
string schema = ServiceSettingsDictionary.GetSchemaName();
if (!string.IsNullOrEmpty(schema))
{
modelBuilder.HasDefaultSchema(schema);
}
modelBuilder.Conventions.Add(
new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
"ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString()));
base.OnModelCreating(modelBuilder);
}
}
}
tblField.cs
namespace cimsService.Models
{
using Microsoft.WindowsAzure.Mobile.Service.Tables;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("tblField")]
public partial class tblField
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public tblField()
{
tblEntries = new HashSet<tblEntry>();
tblFieldDetails = new HashSet<tblFieldDetail>();
tblLink_FieldToAsset = new HashSet<tblLink_FieldToAsset>();
tblLink_FieldToConfiguration = new HashSet<tblLink_FieldToConfiguration>();
tblLink_FieldToForm = new HashSet<tblLink_FieldToForm>();
tblLink_FieldToLocation = new HashSet<tblLink_FieldToLocation>();
tblLink_FieldToTemplate_Asset = new HashSet<tblLink_FieldToTemplate_Asset>();
}
[Key]
public int keyFieldID { get; set; }
[Required]
public string FieldText { get; set; }
public string FieldDefaultEntry { get; set; }
public string ParameterDefaultEntry { get; set; }
[StringLength(50)]
public string FieldType { get; set; }
public int? fk_FieldGroupID { get; set; }
[StringLength(1)]
public string fillFlag { get; set; }
public bool? isHidden { get; set; }
public int? DisplayOrder { get; set; }
public int? PercentageWidth { get; set; }
public DateTime? StartEffDT { get; set; }
public DateTime? EndEffDT { get; set; }
[StringLength(50)]
public string SecurityLevels { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblEntry> tblEntries { get; set; }
public virtual tblFieldGroup tblFieldGroup { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblFieldDetail> tblFieldDetails { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblLink_FieldToAsset> tblLink_FieldToAsset { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblLink_FieldToConfiguration> tblLink_FieldToConfiguration { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblLink_FieldToForm> tblLink_FieldToForm { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblLink_FieldToLocation> tblLink_FieldToLocation { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblLink_FieldToTemplate_Asset> tblLink_FieldToTemplate_Asset { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Index]
[TableColumn(TableColumnType.CreatedAt)]
public DateTimeOffset? CreatedAt { get; set; }
[TableColumn(TableColumnType.Deleted)]
public bool Deleted { get; set; }
[Index]
[TableColumn(TableColumnType.Id)]
[MaxLength(36)]
public string Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[TableColumn(TableColumnType.UpdatedAt)]
public DateTimeOffset? UpdatedAt { get; set; }
[TableColumn(TableColumnType.Version)]
[Timestamp]
public byte[] Version { get; set; }
}
}
答案 0 :(得分:1)
很抱歉这么明显,但你的DTO需要一个Id字段。把它变成一个字符串。这是移动服务SDK工作所必需的。
答案 1 :(得分:1)
正如Adrian所说,Id属性是必需的。查看上面的DTOtblField类,因为您继承自EntityData,所以您不必(也不应该)显式定义Id属性,因为它是在EntityData中定义的,但我也注意到您的DTO是由工具自动生成,所以我想知道工具是否有可能在发布时或在其他步骤中重写对象。
除非该工具提供了一种指定它应该从EntityData继承的方法,否则我建议您使用以下单独的文件:
namespace cimsmobileService.DataObjects
{
public partial class DTOtblField : EntityData
{
}
}
这将确保您的修改保持不变,即使工具重新生成DTO也是如此。