2017-04-27 14 views
0

私は、Azureに基づいてモバイルアプリケーション用の.NETバックエンドサービスを開発しています。 私はすでにSQLデータベースを持っており、バックエンドにのみ接続したいと思っています。 だから、私はこのガイドを、次のよ: https://blogs.msdn.microsoft.com/wsdevsol/2014/07/17/walkthrough-attaching-an-azure-sql-database-to-your-net-backend/一般的なMappedEntityDomainManagerを開発する

問題は、私はすべてのDTOを処理するための汎用的なSimpleMappedEntityDomainManagerを作るために行くときということです - モデルのマッピング、私は若干の誤差が出ます。

私はすでに ...(もはやコンストラクタでApiServiceが必要です)MappedEntityDomainManagerを固定しているしかし、私はこれらを調整することはできません。

「マッパーはFindTypeMapForの定義が含まれていません」

"ジェネリック型 'PropertyAccessorを< < TEntityType >>' を使用するには、1型引数が必要です"

現在のコード:

using AutoMapper; 
using Microsoft.Azure.Mobile.Server; 
using Microsoft.Azure.Mobile.Server.Tables; 
using System; 
using System.Data.Entity; 
using System.Linq.Expressions; 
using System.Net.Http; 
using System.Reflection; 
using System.Threading.Tasks; 
using System.Web.Http; 
using System.Web.Http.OData; 

namespace TestMobileService.Models 
{ 
    //Utilities for Hooking up models 
    public static class MySqlFuncs 
    { 
     [DbFunction("SqlServer", "STR")] 
     public static string StringConvert(long number) 
     { 
      return number.ToString(); 
     } 
     [DbFunction("SqlServer", "LTRIM")] 
     public static string LTRIM(string s) 
     { 
      return s == null ? null : s.TrimStart(); 
     } 
     // Can only be used locally. 
     public static long LongParse(string s) 
     { 
      long ret; 
      long.TryParse(s, out ret); 
      return ret; 
     } 
    } 


    public class SimpleMappedEntityDomainManager<TData, TModel> 
     : MappedEntityDomainManager<TData, TModel> 
     where TData : class, ITableData, new() 
     where TModel : class 
    { 
     private Expression<Func<TModel, object>> dbKeyProperty; 

     public SimpleMappedEntityDomainManager(DbContext context, 
      HttpRequestMessage request, Expression<Func<TModel, object>> dbKeyProperty) 
      : base(context, request) 
     { 
      this.dbKeyProperty = dbKeyProperty; 
     } 

     public override SingleResult<TData> Lookup(string id) 
     { 
      return this.LookupEntity(GeneratePredicate(id)); 
     } 
     public override Task<TData> UpdateAsync(string id, Delta<TData> patch) 
     { 
      return this.UpdateEntityAsync(patch, ConvertId(id)); 
     } 
     public override Task<bool> DeleteAsync(string id) 
     { 
      return this.DeleteItemAsync(ConvertId(id)); 
     } 

     private object ConvertId(string id) 
     { 
      var m = Mapper.FindTypeMapFor<TData, TModel>(); 
      var keyPropertyAccessor = GetPropertyAccessor(this.dbKeyProperty); 
      var pmForId = m.GetExistingPropertyMapFor(new PropertyAccessor(keyPropertyAccessor)); 
      TData tmp = new TData() { Id = id }; 
      var convertedId = pmForId.CustomExpression.Compile().DynamicInvoke(tmp); 
      return convertedId; 
     } 

     private static Expression<Func<TModel, bool>> GeneratePredicate(string id) 
     { 
      var m = Mapper.FindTypeMapFor<TModel, TData>(); 
      var pmForId = m.GetExistingPropertyMapFor(new PropertyAccessor(typeof(TData).GetProperty("Id"))); 
      var keyString = pmForId.CustomExpression; 
      var predicate = Expression.Lambda<Func<TModel, bool>>(
       Expression.Equal(keyString.Body, Expression.Constant(id)), 
       keyString.Parameters[0]); 
      return predicate; 
     } 

     private PropertyInfo GetPropertyAccessor(Expression exp) 
     { 
      if (exp.NodeType == ExpressionType.Lambda) 
      { 
       var lambda = exp as LambdaExpression; 
       return GetPropertyAccessor(lambda.Body); 
      } 
      else if (exp.NodeType == ExpressionType.Convert) 
      { 
       var convert = exp as UnaryExpression; 
       return GetPropertyAccessor(convert.Operand); 
      } 
      else if (exp.NodeType == ExpressionType.MemberAccess) 
      { 
       var propExp = exp as System.Linq.Expressions.MemberExpression; 
       return propExp.Member as PropertyInfo; 
      } 
      else 
      { 
       throw new InvalidOperationException("Unexpected expression node type: " + exp.NodeType); 
      } 
     } 
    } 
} 

ご存じですか?

答えて

0

私はこの解決策になりました。 それは完全に動作します。

using Microsoft.Azure.Mobile.Server; 
using System; 
using System.Data.Entity; 
using System.Net.Http; 
using System.Threading.Tasks; 
using System.Web.Http; 
using System.Web.Http.OData; 

namespace TestRareMobileService.Models 
{ 
    public class SimpleMappedEntityDomainManager<TData, TModel> 
    : MappedEntityDomainManager<TData, TModel> 
    where TData : class, Microsoft.Azure.Mobile.Server.Tables.ITableData 
    where TModel : class 
    { 
     private Func<TModel, string> keyString; 
     public SimpleMappedEntityDomainManager(DbContext context, 
      HttpRequestMessage request, Func<TModel, string> keyString) 
      : base(context, request) 
     { 
      this.keyString = keyString; 
     } 
     public override SingleResult<TData> Lookup(string id) 
     { 
      return this.LookupEntity(p => this.keyString(p) == id); 
     } 
     public override Task<TData> UpdateAsync(string id, Delta<TData> patch) 
     { 
      return this.UpdateEntityAsync(patch, id); 
     } 
     public override Task<bool> DeleteAsync(string id) 
     { 
      return this.DeleteItemAsync(id); 
     } 
    } 
} 
関連する問題