【问题标题】:Can't find a property nameId in Azure mobile services在 Azure 移动服务中找不到属性 nameId
【发布时间】:2016-03-24 13:44:30
【问题描述】:

我正在尝试关注此tutorial 并为项目创建移动后端。我正在尝试获取 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 => 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; }

    }
}

【问题讨论】:

    标签: c# asp.net-mvc azure asp.net-web-api azure-mobile-services


    【解决方案1】:

    正如 Adrian 所说,Id 属性是必需的。查看上面的 DTOtblField 类,由于您是从 EntityData 继承的,因此您不必(也不应该)显式定义 Id 属性,正如 EntityData 中定义的那样,但我也注意到您的 DTO 是由工具自动生成,所以我想知道工具是否有可能在发布时或其他步骤期间重写您的对象。

    除非该工具为您提供了一种方法来指定它应该从 EntityData 继承,否则我建议您拥有一个单独的文件,其中包含以下内容:

    namespace cimsmobileService.DataObjects
    {
    
        public partial class DTOtblField : EntityData
        {
        }
    }
    

    这将确保您的修改得以保留,即使 DTO 由该工具重新生成。

    【讨论】:

      【解决方案2】:

      很抱歉这么明显,但您的 DTO 需要一个 Id 字段。让它成为一个字符串。这是移动服务 SDK 工作所必需的。

      【讨论】:

      • 但该指南说将 Id 添加到字段模型,然后使用 automapper 库将其映射到 dto 模型。
      • 我将 Id 字段添加到 DTO 仍然给我同样的信息。
      • 我运行了调试器,它没有命中 DTOtblFieldDomainManager 中的 GetKey 方法。是不是应该在 get 调用后在某一时刻点击 GetKey 方法。
      • 刚回到这个,我注意到了 Fabios 的回复和自动生成。我也怀疑自动生成。很遗憾,我不熟悉您使用的工具。
      • 我认为该工具不会覆盖任何内容。 WebApiConfig 中的初始化程序 - ClearDatabaseSchemaIfModelChanges。它是否覆盖所有内容并插入数据,并且模型中的所有表是否都需要通过插入数据来初始化。如果是这样,有没有办法初始化但使用现有数据。
      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多