您知道如何使用OData语法更新WCF数据服务中的实体而不使用实体的密钥属性。
例如,实体:
public class Product
{
[Key]
public int Id { get; set; }
public string Reference { get; set; }
}
我想提出这个要求:
PUT myservice.svc/Product('REFXX')
与'REFXXX'对应的执行Reference属性(这是唯一的)。
有什么想法吗?
答案 0 :(得分:0)
目前无法做到这一点 - 问题是如果您将以下请求传递给服务器(PUT myservice.svc / Product('REFXX')),服务器将如何知道REFXX是该值的值独特的财产,而不是关键财产。
如果您确实想要根据唯一属性更新客户端,请确保服务器将该唯一属性公开为密钥。
由于 PRATIK
答案 1 :(得分:0)
我编写了一个IDispatchMessageInspector,解析了url,并使用正确的语法和真实密钥替换了request参数中的match元素。我知道密钥不是具有特定用户代理的真正“密钥”,或者是Service.svc / Entity(SecondaryKey = value)的语法,它通常用于多个pk。
所以在AfterReceiveRequest方法中,进程是:
使用Service.svc / Entity(PKValue)更改请求的匹配元素
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
if (request.Properties.ContainsKey("UriTemplateMatchResults") && HttpContext.Current != null)
{
//get match for current request
UriTemplateMatch match = (UriTemplateMatch)request.Properties["UriTemplateMatchResults"];
Utils.ODataBasicUriParser uriParser = new Utils.ODataBasicUriParser(match.RequestUri.PathAndQuery);
//verify if this is a SecondaryKey request
if (uriParser.IsEntityQuery && uriParser.IsSecondaryKeyQuery)
{
//TODO this syntax is also used for entities with multiple pk's, test it
//get a new data context
//TODO see if this can be improved, avoid two datacontext for one request
DataContext ctx = new DataContext();
Type outType;
//get entity type name from the service name
string entityName = DataContext.GetEntityNameByServiceName(uriParser.EntityServiceName);
//get the pk for the entity
string id = ctx.GetEntityId(entityName, uriParser.EntityKey, uriParser.EntityId, out outType);
//verify if the pk has been found or cancel this to continue with standart request process
if (string.IsNullOrEmpty(id))
{
Trace.TraceWarning(string.Format("Key property not found for the the entity:{0}, with secondaryKeyName:{1} and secondaryKeyValue:{2}",
entityName, uriParser.EntityKey, uriParser.EntityId));
return System.Net.HttpStatusCode.NotFound;
}
//in odata syntax quotes are required for string values, nothing for numbers
string quote = outType.FullName == typeof(Int32).FullName || outType.FullName == typeof(Int64).FullName ? string.Empty : "'";
//build the new standart resource uri with the primary key
var newUri = new Uri(string.Format("{0}/{1}({2}{3}{2})", match.BaseUri.ToString(), uriParser.EntityServiceName, quote, id));
//create a new match to replace in the current request, with the new Uri
UriTemplateMatch newMatch = NewMatch(match, newUri);
//set request values
request.Properties["UriTemplateMatchResults"] = newMatch;
request.Headers.To = newUri;
request.Properties.Via = newUri;
}
}
return null;
}
UriTemplateMatch NewMatch(UriTemplateMatch match, Uri newUri)
{
UriTemplateMatch newMatch = new UriTemplateMatch();
newMatch.RequestUri = newUri;
newMatch.Data = match.Data;
newMatch.BaseUri = match.BaseUri;
return newMatch;
}
适合我目前的需求