ADO.NET 数据服务执行CRUD

第一步:定义实体类,注意DataServiceKeyAtrribute特性

[DataServiceKey("Id")]
    public class Phone
    {
        public int Id
        {
            get;
            set;
        }

        public string Number
        {
            get;
            set;
        }

        public Student Stu
        {
            get;
            set;
        }
    }

    [DataServiceKey("Id")]
    public class Student
    {
        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public string Address
        {
            get;
            set;
        }

        public IList<Phone> Phones
        {
            get;
            set;
        }
    }


 

第二步:定义服务端Context,如果要使自定义的Conetxt能够执行CRUD,就必须实现 IUpdatable 接口;如下

 

    public class StudentContext : IUpdatable
    {
        static IList<Student> _students;
        static IList<Phone> _phones;

        static StudentContext()
        {
            _students = new List<Student>() 
                {
                    new Student(){Id=1,Name="Stu 1",Address="xxxxxxx",Phones = new List<Phone>()},
                    new Student(){Id=2,Name="Stu 2",Address="xxxxxxx",Phones = new List<Phone>()},
                };
            _phones = new List<Phone>()
            {
                new Phone(){Id=1,Number="110"},
                new Phone(){Id=2,Number="119"},
                new Phone(){Id=3,Number="120"},
            };

            _students[0].Phones.Add(_phones[0]);
            _phones[0].Stu = _students[0];
            _students[0].Phones.Add(_phones[1]);
            _phones[1].Stu = _students[0];
            _students[1].Phones.Add(_phones[2]);
            _phones[2].Stu = _students[1];
        }

        public IQueryable<Student> Students
        {
            get
            {
                return _students.AsQueryable<Student>();
            }
        }

        public IQueryable<Phone> Phones
        {
            get
            {
                return _phones.AsQueryable<Phone>();
            }
        }

        public object CreateResource(string containerName, string fullTypeName)
        {
            Type t = Type.GetType(fullTypeName, true);
            object resource = Activator.CreateInstance(t);
            if (containerName == "Students")
            {
                _students.Add(resource as Student);
            }
            if (containerName == "Phones")
            {
                _phones.Add(resource as Phone);
            }
            return resource;
        }

        public void DeleteResource(object targetResource)
        {
            if (targetResource.GetType() == typeof(Student))
            {
                _students.Remove(targetResource as Student);
                return;
            }
            if (targetResource.GetType() == typeof(Phone))
            {
                _phones.Remove(targetResource as Phone);
            }
            throw new NotSupportedException("Type not found");
        }

        public object GetResource(IQueryable query, string fullTypeName)
        {
            object resource = query.Cast<object>().SingleOrDefault();

            // fullTypeName can be null for deletes  
            if (fullTypeName != null && resource.GetType().FullName != fullTypeName)
            {
                throw new ApplicationException("Unexpected type for this resource.");
            }
            return resource;
        }

        public object GetValue(object targetResource, string propertyName)
        {
            // get the property info using reflection
            var targetType = targetResource.GetType();
            var targetProperty = targetType.GetProperty(propertyName);

            // retrun the value of the property
            return targetProperty.GetValue(targetResource, null);
        }

        public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            // get the property info using reflection
            Type targetType = targetResource.GetType();
            PropertyInfo property = targetType.GetProperty(propertyName);

            // set the property value
            property.SetValue(targetResource, propertyValue, null);
        }

        public object ResetResource(object resource)
        {
            return resource;
        }

        public object ResolveResource(object resource)
        {
            return resource;
        }

        public void SaveChanges()
        {
            // object in memory - do nothing
        }

        public void ClearChanges()
        {
            throw new NotImplementedException();
        }

        public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
        {
            PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
            if (pi == null)
                throw new Exception("Can't find property");
            IList collection = (IList)pi.GetValue(targetResource, null);
            collection.Add(resourceToBeAdded);

        }

        public void SetReference(object targetResource, string propertyName, object propertyValue)
        {
            ((IUpdatable)this).SetValue(targetResource, propertyName, propertyValue);
        }

        public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {
            PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
            if (pi == null)
                throw new Exception("Can't find property");
            IList collection = (IList)pi.GetValue(targetResource, null);
            collection.Remove(resourceToBeRemoved);

        }
    }


 第三步:创建一个Web Application 项目,添加一个WCF Data Service项(比如我们取名为“StudentDataService”),CS代码如下;

    public class StudentDataService : DataService<StudentContext>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }


注意:泛型参数为之前我们定义的Context,InitializeService方法内部的前两行代码用以设置Client端调用的权限,我们设置为对所有的数据(*)拥有所有权限。

我们把StudentDataService.svc部署到IIS,假设URL为"http://localhost:/StudentDataService.svc/"

 

第四步:客户端调用,可以添加Service References,共享服务器端实体类,也可以在客户端定义和服务器端相同的实体类(Phone 和 Student),注意要和服务器端一致;示 例 如下:

            Uri uri = new Uri(@"http://localhost:52758/StudentDataService.svc/");

            DataServiceContext ctx = new DataServiceContext(uri);
            DataServiceQuery<Student> query = ctx.CreateQuery<Student>("Students");

            var stu = query.FirstOrDefault();

            Phone phone = new Phone() { Id = 4, Number = "140" };
            Phone phone1 = new Phone() { Id = 5, Number = "150" };
            ctx.AddRelatedObject(stu, "Phones", phone);
            ctx.SetLink(phone, "Stu", stu);
            ctx.AddRelatedObject(stu, "Phones", phone1);
            ctx.SetLink(phone1, "Stu", stu);
            ctx.SaveChanges();

 

                            更多关于Odata的了解请Email我:KKevinn@126.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值