注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

WCF的学习总结(八)RIA services数据库的访问  

2012-11-13 20:53:06|  分类: NET(C#) |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 

WCF的学习总结(八)RIA services数据库的访问

虽然说是RIA,但其实它是把WCF进行了封装,让你误认为他很简单,学习RIA services要学会lamda表达式和linq to sql,至少要懂一些,这样用起来至少不会太绕路。

本章主要介绍RIA返回实体类,非实体类(POCO类)和自定义的数据实体类的方法,然后会同时给大家介绍Silverlight4的相应的开发方法,但那个得另外再开专门的博文了。先介绍第一种,返回实体类:

返回实体类对于SQL SERVER来说,太方便了,因为VS本身提供了对ADO Entity的的支持,在中添加ADO.NET实体数据模型,按步骤即可一次生成相应的代码。打开对应的文件,发现熟悉吧,和用其它工具生成的实体类,基本相似,不过多了些辅助的东西。基本如下:

    [EdmEntityTypeAttribute(NamespaceName="YaoJieDBModel", Name="Person_Image")]

    [Serializable()]

    [DataContractAttribute(IsReference=true)]

    public partial class Person_Image : EntityObject

    {

        #region 工厂方法

   

        /// <summary>

        /// 创建新的 Person_Image 对象。

        /// </summary>

        /// <param name="image_id">image_id 属性的初始值。</param>

        public static Person_Image CreatePerson_Image(global::System.Int32 image_id)

        {

            Person_Image person_Image = new Person_Image();

            person_Image.image_id = image_id;

            return person_Image;

        }

 

        #endregion

 

        #region 基元属性

   

        /// <summary>

        /// 没有元数据文档可用。

        /// </summary>

        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]

        [DataMemberAttribute()]

        public global::System.Int32 image_id

        {

            get

            {

                return _image_id;

            }

            set

            {

                if (_image_id != value)

                {

                    Onimage_idChanging(value);

                    ReportPropertyChanging("image_id");

                    _image_id = StructuralObject.SetValidValue(value);

                    ReportPropertyChanged("image_id");

                    Onimage_idChanged();

                }

            }

        }

        private global::System.Int32 _image_id;

        partial void Onimage_idChanging(global::System.Int32 value);

        partial void Onimage_idChanged();

   

        /// <summary>

        /// 没有元数据文档可用。

        /// </summary>

        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]

        [DataMemberAttribute()]

        public global::System.Byte[] image_data

        {

            get

            {

                return StructuralObject.GetValidValue(_image_data);

            }

            set

            {

                Onimage_dataChanging(value);

                ReportPropertyChanging("image_data");

                _image_data = StructuralObject.SetValidValue(value, true);

                ReportPropertyChanged("image_data");

                Onimage_dataChanged();

            }

        }

        private global::System.Byte[] _image_data;

        partial void Onimage_dataChanging(global::System.Byte[] value);

        partial void Onimage_dataChanged();

   

        /// <summary>

        /// 没有元数据文档可用。

        /// </summary>

        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]

        [DataMemberAttribute()]

        public global::System.String image_type

        {

            get

            {

                return _image_type;

            }

            set

            {

                Onimage_typeChanging(value);

                ReportPropertyChanging("image_type");

                _image_type = StructuralObject.SetValidValue(value, true);

                ReportPropertyChanged("image_type");

                Onimage_typeChanged();

            }

        }

        private global::System.String _image_type;

        partial void Onimage_typeChanging(global::System.String value);

        partial void Onimage_typeChanged();

 

        #endregion

 

   

        #region 导航属性

   

        /// <summary>

        /// 没有元数据文档可用。

        /// </summary>

        [XmlIgnoreAttribute()]

        [SoapIgnoreAttribute()]

        [DataMemberAttribute()]

        [EdmRelationshipNavigationPropertyAttribute("YaoJieDBModel", "FK_PERSON_FK_PERSON_PERSON_I", "Person")]

        public EntityCollection<Person> Person

        {

            get

            {

                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Person>("YaoJieDBModel.FK_PERSON_FK_PERSON_PERSON_I", "Person");

            }

            set

            {

                if ((value != null))

                {

                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Person>("YaoJieDBModel.FK_PERSON_FK_PERSON_PERSON_I", "Person", value);

                }

            }

        }

 

        #endregion

 

    }

再看相应的域服务类:

    [EnableClientAccess()]

    public class DomSqlService : LinqToEntitiesDomainService<YaoJieDBEntities>

与空的域服务类有所不同,继承的父类有所不同,空的域服务类如下:

    // TODO: 创建包含应用程序逻辑的方法。

    [EnableClientAccess()]

    public class DomDbAccess : DomainService

与上面的类相对应的自动生成了查询和更新插入删除等操作的函数:

        public IQueryable<Attend_Rec> GetAttend_Rec()

        {

            return this.ObjectContext.Attend_Rec;

        }

        public void InsertAttend_Rec(Attend_Rec attend_Rec)

        {

            if ((attend_Rec.EntityState != EntityState.Detached))

            {

                this.ObjectContext.ObjectStateManager.ChangeObjectState(attend_Rec, EntityState.Added);

            }

            else

            {

                this.ObjectContext.Attend_Rec.AddObject(attend_Rec);

            }

        }

 

        public void UpdateAttend_Rec(Attend_Rec currentAttend_Rec)

        {

            this.ObjectContext.Attend_Rec.AttachAsModified(currentAttend_Rec, this.ChangeSet.GetOriginal(currentAttend_Rec));

        }

 

        public void DeleteAttend_Rec(Attend_Rec attend_Rec)

        {

            if ((attend_Rec.EntityState != EntityState.Detached))

            {

                this.ObjectContext.ObjectStateManager.ChangeObjectState(attend_Rec, EntityState.Deleted);

            }

            else

            {

                this.ObjectContext.Attend_Rec.Attach(attend_Rec);

                this.ObjectContext.Attend_Rec.DeleteObject(attend_Rec);

            }

        }

这是最简单也是最方便的一种,但可惜的是,这种方法目前只支持SQL SERIVER,如果你要是用别的数据库那么只好用其它的方法了,这就是第二种,返回非实体类,或者叫自定义类,注意,不是自定义的实体类。

新建立一个空的域服务类,写如下代码:

注意:此类在域服务类外:

    public class Sovereign

    {

        [Key]

        public int UniqueId { get; set; }

        public string Name { get; set; }

        public string House { get; set; }

        public string Dominion { get; set; }

        public int ReignStart { get; set; }

        public int ReignEnd { get; set; }

        public string Sobriquet { get; set; }

 

        public List<Sovereign> FetchSovereigns()

        {

            List<Sovereign> sovereignList = new List<Sovereign>

            {

            new Sovereign()

                {UniqueId = 1,

                 Name = "John",

                 House = "Plantagenet",

                 Dominion = "Angevin Empire",

                 ReignStart = 1167,

                 ReignEnd = 1216,

                 Sobriquet = "Lackland"

                },

            new Sovereign()

                {UniqueId = 2,

                 Name = "Charles",

                 House = "Stuart",

                 Dominion = "England, Scotland, & Ireland",

                 ReignStart = 1625,

                 ReignEnd = 1649,

                 Sobriquet = "The Martyr"

                },

            new Sovereign()

                {UniqueId = 3,

                 Name = "William",

                 House = "Dunkeld",

                 Dominion = "Scotland",

                 ReignStart = 1165,

                 ReignEnd = 1249,

                 Sobriquet = "The Lion"

                },  

            new Sovereign()

                {UniqueId = 4,

                 Name = "Elizabeth",

                 House = "Tudor",

                 Dominion = "England",

                 ReignStart = 1555,

                 ReignEnd = 1609,

                 Sobriquet = "The Virgin Queen"

                },

            new Sovereign()

                {UniqueId = 5,

                 Name = "Ivan",

                 House = "Vasilyevich",

                 Dominion = "Russia",

                 ReignStart = 1533,

                 ReignEnd = 1584,

                 Sobriquet = "The Terrible"

                },

            new Sovereign()

                {UniqueId = 6,

                 Name = "Charles",

                 House = "Valois",

                 Dominion = "France",

                 ReignStart = 1380,

                 ReignEnd = 1422,

                 Sobriquet = "The Mad"

                }

            };

            return sovereignList;

        }

然后再在域服务类内:

    [EnableClientAccess()]

    public class DomDbAccess : DomainService

    {

        public IEnumerable<Sovereign> GetSovereignsByReignEnd(int ReignedBefore)

        {

            Sovereign sovereign = new Sovereign();

            return sovereign.FetchSovereigns().Where<Sovereign>(p => p.ReignEnd <= 1500);

        }

    }

这里捎带说一句,返回IEnumerable和IQueryable的区别是:

前者是全部生成然后再对数据进行处理,而后者是处理好后再进行数据生成,至于哪种方式更合适,看你的具体的应用范围了。

还有一种方法:

同上面一样,在域服务类外:

    [DataContract]

    public class MyTestClass 

    {        

        [DataMember]

        public string[] MyList{ get; set; }

        [DataMember]

        public int MyData { get; set; }

}

然后在域服务类内:

    [EnableClientAccess()]

    public class DomDbAccess : DomainService

    {

        [Invoke]

        public MyTestClass Test(/*string a, string b*/)

        {

            //TODO: ....

            MyTestClass mc = new MyTestClass(); mc.MyList = new string[2];

            mc.MyData = 100;

            mc.MyList[0] = "2222";

            return mc; //返回自定义类型

        }

        protected override void OnError(DomainServiceErrorInfo errorInfo)

        {

            base.OnError(errorInfo);

            //Logger.LogException(errorInfo.Error.Message, errorInfo.Error.StackTrace);

        }

    }

这样用[Invoke]的方式来直接返回自定义的类,invoke的方式是和具体的实体类无关的调用。具体的用法大家可以去查MSDN,包括query,update,delete,insert,invoke,这里有好多目前已经可以省略不写了。大家一定要注意。

最后一种是一种变种,也就是上面提醒注意的实体类的组合类,它的应用范围很明确,比如要查找一个类似于视图的几个表在一起的数据,你当然可以建立视图再生成实体类,但如果你想偷懒,就可以使用这种方法:

在域服务类的元数据类文件里,添加:

    [DataContract]

    public class ParamStruct

    {

        [DataMember]

        [Key]

        public int id { get; set; }

        [DataMember]

        public string worksn { get; set; }

    }

这里需要注意的是,一定要有[key]这个属性,包括前面带KEY的也一样。不能省略。

然后你就可以像实体类一样操作了,在生成的类里写操作函数如下:

        public IQueryable<ParamStruct> GetAttend_RecStruct()

        {

            var ps = from f in this.ObjectContext.Attend_Rec

                     select new ParamStruct { id = f.attend_record_id, worksn = f.name };

            return ps;

        }

明白了吧。

前台调用的方法,会在下一章里进行介绍,这里就不细说了,今天就到此,正如先贤所讲:

锲而不舍,金石可镂。

  评论这张
 
阅读(764)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017