处理的OData客户端上的动态属性 [英] dealing with dynamic properties on oData client

查看:148
本文介绍了处理的OData客户端上的动态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的服务器和客户端

以下类

 公共类实体
{
    公共字符串ID {搞定;组;}
    公共字符串名称{;组;}
    公共字典<字符串对象> DynamicProperties {搞定;组;}
}

据我所看到开放式的所有实例介绍有关在服务器端具有动态特性,但在客户端上的属性必须明确declared.When我送从客户端如何发送POST请求动态属性?我不能宣布在客户端上的所有动态属性。有许多属性和每个对象将包含不同的设置在客户端的动态性能。这些动态特性被存储在客户端的DynamicProperties字典。我怎么以上的实体类的对象发送到服务器端,从而使服务器间preT DynamicProperties的内容字典作为动态属性?任何帮助是AP preciated。

===========================后续萨姆的回答=========== ============

 静态无效的主要(字符串[] args1)
    {
        container.Customers.ToList();
        客户newCustomer =新客户();
        newCustomer.Id = 19;
        newCustomer.Properties =新词典<字符串对象>
        {
            {IntProp,9},
            {DateTimeOffsetProp,新的DateTimeOffset(2015年,7,16,1,2,3,4,TimeSpan.Zero)}
            {嗒嗒,哈}
        };
        尝试
        {
            addCustomer(newCustomer);
            container.AddToCustomers(newCustomer);
            container.SaveChanges();
        }
        赶上(例外)
        {        }
        客户newCustomer1 =新客户();
        newCustomer1.Id = 20;
        newCustomer1.Properties =新词典<字符串对象>
        {
            {IntProp,10},
            {目录,北}
        };
        addCustomer(newCustomer1);
        container.AddToCustomers(newCustomer1);
        container.SaveChanges();
        newCustomer1.Properties [DIR] =南下
        container.UpdateObject(newCustomer1);
        container.SaveChanges();
        Console.ReadKey();
    }    私有静态无效addCustomer(客户的客户)
    {
        container.Configurations.RequestPipeline.OnEntryStarting(参数=>
        {
            的foreach(在customer.Properties VAR属性)
            {
                args.Entry.AddProperties(新ODataProperty
                {
                    名称= property.Key,
                    值= property.Value //为枚举,复合型,应该创造ODataEnumValue和ODataComplexValue。
                });
            }
        });
    }

我得到一个错误,说明名为'IntProp多个属性中的一个条目或复数值进行检测。在OData的,重复的属性名称不允许。此外,我怀疑,如果发送对象怎么样我现在做的是一个有效的方法,因为我从一个源获取大量的对象之前创建一个动作每一次,我将它发送到服务器。如果我为每个对象创建一个动作那么作为OData的客户端在内存中保存这些行动可能炸毁的内存。如何处理我的方案?请帮帮我。

此外,还有一个问题,如果我评论在 container.Customers.ToList()失败,说明我试图添加未声明的属性。这是为什么?


解决方案

如果您使用的是<一个href=\"http://blogs.msdn.com/b/odatateam/archive/2014/03/12/how-to-use-odata-client-$c$c-generator-to-generate-client-side-proxy-class.aspx\"相对=nofollow>的OData客户端code发电机,则可以使用部分类定义/检索/保存dyanmic属性。

例如,在你的客户端,您可以定义一个局部类的实体

 公共部分类实体
{
    //动态属性电子邮件
    [全球:: Microsoft.OData.Client.OriginalNameAttribute(电子邮件)]
    公共字符串的电子邮件
    {
        得到
        {
            返回this._Email;
        }
        组
        {
            this.OnEmailChanging(值);
            this._Email =价值;
            this.OnEmailChanged();
            this.OnPropertyChanged(电子邮件);
        }
    }    私人字符串_EMAIL;
    部分无效OnEmailChanging(字符串值);
    部分无效OnEmailChanged();
}

然后,你可以用这个来插入/检索/保存动态属性电子邮件

您可以这样做:

 集装箱集装箱=新容器(新的URI(HTTP:// ...));
实体实体=新实体();
...
entity.Email =XXXX;
container.AddToEntities(实体);
container.SaveChanges();

有关类似的实现,你可以参考我的样本项目

==========迭代2 =====

有关客户端实体的IDictionary&LT;字符串对象&gt; ,我想钩就是你在做什么寻找。

例如,在客户端:

 公共部分类实体
{
    公众的IDictionary&LT;字符串对象&gt;属性{搞定;组; }    .....
}

如果你之前

插入以下codeS它应该工作

container.AddToEntities(实体);

例如:

 实体实体=新实体();
...
entity.Properties =新词典&LT;字符串对象&gt;
{
    {IntProp,9},
    {DateTimeOffsetProp,新的DateTimeOffset(2015年,7,16,1,2,3,4,TimeSpan.Zero)}
};container.Configurations.RequestPipeline.OnEntryStarting(参数=&GT;
{
    的foreach(在entity.Properties VAR属性)
    {
        args.Entry.AddProperties(新ODataProperty
        {
            名称= property.Key,
            值= property.Value
        });
    }
});container.AddToEntities(实体);
container.SaveChanges();

其中, AddProperties 是一个扩展方法。你可以找到它在我的样本项目
 和最新提交

此外,引擎盖方法只适用的OData客户端V6.12或以上。

希望它可以帮助你。

==========迭代3 =====


  1. 首先,你叫下面的方法,

    container.Configurations.RequestPipeline.OnEntryStarting(...);

    这意味着增加将在以后执行被称为动作。在您的codeS,你怎么称呼它的两倍,因此,有两个加入行动。这两项举措将由一个被称为之一,当执行保存 newCustomer1
    那是, newCustomer1 newCustomer 的动态属性(行动1),同时,它会有自己的动态特性(行动2)。这就是为什么你得到重复的属性名例外。


要解决这个问题,你可以续订集装箱。看到我的项目的最新情况。

<醇开始=2>
  • 对于 container.Customers.ToList(),这似乎是一个OData的客户端的问题。

  • I have the following class on both server and client

    public class Entity
    {
        public string Id {get; set;}
        public string Name {get; set;}
        public Dictionary<string, object> DynamicProperties {get; set;}
    }
    

    As far as I have seen all the examples of open type describes about having dynamic properties on the server side, but the properties on the client needs to be explicitly declared.When I send a POST request from the client how do i send the dynamic properties ?. I can't declare all the dynamic properties on the client side. There are numerous properties and each object will contain different set of dynamic properties in the client side. These dynamic properties are stored in the DynamicProperties dictionary in the client side. How do I send the object of above entity class to the server side, so that server will interpret the contents of DynamicProperties dictionary as dynamic properties ?. Any help is appreciated.

    ===========================Follow-up for sam's answer=======================

        static void Main(string[] args1)
        {
            container.Customers.ToList();
            Customer newCustomer = new Customer();
            newCustomer.Id = 19;
            newCustomer.Properties = new Dictionary<string, object>
            {
                {"IntProp", 9},
                {"DateTimeOffsetProp", new DateTimeOffset(2015, 7, 16, 1, 2, 3, 4, TimeSpan.Zero)},
                {"blah","ha"}
            };
            try
            {
                addCustomer(newCustomer);
                container.AddToCustomers(newCustomer);
                container.SaveChanges();
            }
            catch (Exception)
            {
    
            }
            Customer newCustomer1 = new Customer();
            newCustomer1.Id = 20;
            newCustomer1.Properties = new Dictionary<string, object>
            {
                {"IntProp", 10},
                {"dir","north"}
            };
            addCustomer(newCustomer1);
            container.AddToCustomers(newCustomer1);
            container.SaveChanges();
            newCustomer1.Properties["dir"] = "south";
            container.UpdateObject(newCustomer1);
            container.SaveChanges();
            Console.ReadKey();
        }
    
        private static void addCustomer(Customer customer)
        {
            container.Configurations.RequestPipeline.OnEntryStarting(args =>
            {
                foreach (var property in customer.Properties)
                {
                    args.Entry.AddProperties(new ODataProperty
                    {
                        Name = property.Key,
                        Value = property.Value // for enum, complex type, should to create ODataEnumValue and ODataComplexValue.
                    });
                }
            });
        }
    

    I am getting an error stating Multiple properties with the name 'IntProp' were detected in an entry or a complex value. In OData, duplicate property names are not allowed. Also, I doubt if creating an action each time before sending an object like how I am doing now is a valid approach as I get lot of objects from a source and I send it to the server. If I create an action for each object then it might blow up the memory as oData client holds these actions in memory. How do I handle my scenario ?. Kindly help me.

    Also, one more question if I comment the container.Customers.ToList() it fails stating that I am trying to add undeclared properties. Why is that ?

    解决方案

    If you are using OData Client Code Generator, you can use the partial class to define/retrieve/save the dyanmic properties.

    For example, in your client side, you can define a partial class for your Entity

    public partial class Entity
    {
        // Dynamic property "Email"
        [global::Microsoft.OData.Client.OriginalNameAttribute("Email")]
        public string Email
        {
            get
            {
                return this._Email;
            }
            set
            {
                this.OnEmailChanging(value);
                this._Email = value;
                this.OnEmailChanged();
                this.OnPropertyChanged("Email");
            }
        }
    
        private string _Email;
        partial void OnEmailChanging(string value);
        partial void OnEmailChanged();
    }
    

    Then, you can use this to insert/retrieve/save the dynamic property "Email".

    You can do like this:

    Container container = new Container(new Uri("http://..."));
    Entity entity = new Entity();
    ...
    entity.Email = "xxxx";
    container.AddToEntities(entity);
    container.SaveChanges();
    

    For similar implementation, you can refer to my sample project.

    ========== iteration 2 ================

    For client Entity class with IDictionary<string,object>, I think the hook is what you're looking for.

    For example, on client side:

    public partial class Entity
    {
        public IDictionary<string, object> Properties { get; set; }
    
        .....
    }
    

    It should work if you insert the following codes before

    container.AddToEntities(entity);

    For example:

    Entity entity = new Entity();
    ...
    entity.Properties = new Dictionary<string, object>
    {
        {"IntProp", 9},
        {"DateTimeOffsetProp", new DateTimeOffset(2015, 7, 16, 1, 2, 3, 4, TimeSpan.Zero)}
    };
    
    container.Configurations.RequestPipeline.OnEntryStarting(args =>
    {
        foreach (var property in entity.Properties)
        {
            args.Entry.AddProperties(new ODataProperty
            {
                Name = property.Key,
                Value = property.Value
            });
        }
    });
    
    container.AddToEntities(entity);
    container.SaveChanges();
    

    Where, AddProperties is an extension method. You can find it in my sample project and the latest commit

    Besides, the hood method only works with OData Client V6.12 or above.

    Hope it can help you.

    ========== iteration 3 ================

    1. First, you call the following method,

      container.Configurations.RequestPipeline.OnEntryStarting(...);

      It means to add an action which will be called in later execution. In your codes, you call it twice, So, there are two actions added. These two actions will be called one by one when execute to save your newCustomer1 That's, newCustomer1 will have newCustomer's dynamic properties (action 1), meanwhile, it will have its own dynamic properties (action 2). That's why you got the duplicate property name exception.

    To resolve it, you can just to renew a Container. See my project's update.

    1. For container.Customers.ToList(), it seems an OData client issue.

    这篇关于处理的OData客户端上的动态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆