0

我使用WCF OData 客户端使用 OData-Service 。在我的应用程序中,当创建实体时,链接属性默认设置为对象:

var defaultPackage = _service.GetDefaultPackage();
var newCar = new Car
{
    Key = "Unique identifier",
    Package = defaultPackage,
    Name = _name
};
_odata.AddToEntity(newCar);
_odata.SetLink(newCar, nameof(Car.Package), newCar.Package);

然后用户可以通过用户界面更改汽车的值。实例的非原始属性的更改被自动传输到服务上下文。这是通过 的INotifyPropertyChanged接口自动完成的car(此接口由 odata 代码生成器为所有实体自动实现)。

private void PropertyChanged(object sender, PropertyChangedEventArgs e)
{ 
    var car = (Car)sender;
    var newValue = GetPropertyValueByReflection(car, e.PropertyName);
    _odata.SetLink(car, e.PropertyName, newValue);
}

除其他外,用户可以删除汽车的包裹。所以属性Package获得了价值null

现在解决方案的问题是,服务上下文不会重置链接Package,而是将其传输_odata.SaveChanges(SaveChangesOptions.Batch)到服务器。这是批处理请求:

--batch_0abebbdc-969a-475a-b1da-a94a1733c6ae
Content-Type: multipart/mixed; boundary=changeset_3e2db159-7696-44af-bb51-00d2f48ed944

--changeset_3e2db159-7696-44af-bb51-00d2f48ed944
Content-Type: application/http
Content-Transfer-Encoding: binary

POST http://some-url.to/odata/Cars/Car HTTP/1.1
Content-ID: 5
Content-Type: application/atom+xml
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    <id />
    <title />
    <updated>2017-06-21T10:58:55Z</updated>
    <author>
        <name />
    </author>
    <content type="application/xml">
        <m:properties>
            <d:Key>Unique identifier</d:Key>
            <d:Name>VW Caddy</d:Name>
        </m:properties>
    </content>
</entry>
--changeset_3e2db159-7696-44af-bb51-00d2f48ed944
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE $5/$links/Package HTTP/1.1
Content-ID: 10
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services

--changeset_3e2db159-7696-44af-bb51-00d2f48ed944--
--batch_0abebbdc-969a-475a-b1da-a94a1733c6ae--

服务器回答错误,因为没有要删除的链接。有没有人知道这个问题的解决方案,因为它被描述用于SetLink(source, propertyName, null)删除链接。

4

1 回答 1

0

最后我找到了一个现在适合我的解决方案。如果实体是新的并且有链接集,SetLink(source, propertyName, null)则不能使用。而不是DetachLink(source, propertyName, oldTarget)必须使用。我通过以下方式实现这一点:

private void PropertyChanged(object sender, PropertyChangedEventArgs e)
{ 
    var car = (Car)sender;
    var newValue = GetPropertyValueByReflection(car, e.PropertyName);
    object existingTarget;
    if ((newValue == null) && IsAdded(car) &&
         ThereExistsAnExistingLink(car, e.PropertyName, out existingTarget))
        _odata.DetachLink(car, e.PropertyName, existingTarget);
    else
        _odata.SetLink(car, e.PropertyName, newValue);
}

private bool IsAdded(object entity)
{
    return _odata.GetEntityDescriptor(entity).State.HasFlag(EntityStates.Added);
}

private bool ThereExistsAnExistingLink(object entity, 
                                       string propertyName, 
                                       out object existingTarget)
{
    var linkDescriptor = _context.Links.FirstOrDefault(
                           ld => ld.Source == _source && 
                                 ld.SourceProperty == _sourceProperty &&
                                !ld.HasStates(EntityStates.Detached)
                           );
    if (linkDescriptor != null)
    {
        existingTarget = linkDescriptor.Target;
        return true;
    }
    existingTarget = null;
    return false;
}
于 2017-07-04T05:52:45.150 回答