我正在为基于Azure的移动应用开发.NET后端服务。 我已经有一个sql数据库,我只想将它附加到后端。 所以,我遵循本指南: https://blogs.msdn.microsoft.com/wsdevsol/2014/07/17/walkthrough-attaching-an-azure-sql-database-to-your-net-backend/
问题在于,当我去制作一个通用的SimpleMappedEntityDomainManager来处理所有dto模型映射时,我会遇到一些错误。
我已经修复了MappedEntityDomainManager(在构造函数中不再需要ApiService)... 但我无法调整这些:
" Mapper不包含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 :(得分: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);
}
}
}