MySQL CodeFirst的布置与注意事项

mysql+ef的部署相较mssql+ef来说复杂一些。我之感触就安排难度在插件版本造成的各种非兼容问题。另外参考了众博客,将多独博客里之涉综合才可以实现,因为不是每个人之操作都同那些博客作者描述的情况一致,不过解决以后外还吓说。现在从零开始操作mysql+CodeFirst的兑现,总结自身之布过程。先保证安装并打开了mysql数据库:

</br>

1.新建控制台项目

搞事前言


前面同一首博客,我们针对XMPPFramework的报到注册功能及逻辑做了详尽的认证,用户登录成功后,我们得举行的饶是得到即账号的好友列表和个人信息,今天眼看无异于篇博客就是针对好友列表的相干逻辑与代理方来开一下执教说明.我们事先看看SDChat中之好友列表示意图.

</br>

2.当次包管理器控制台里依次安装(注意:EF版本一定要低,另外第②暨第③保证版本相同,因为③暨②生据关系,版本不等同会促成有题目)
①Install-Package EntityFramework -Version
6.1.3

XMPPFramework中好友关系说明说


每当XMPPFramework中也,好友关系是可以经过订阅来兑现的,也就是说A与B相互订阅,那么A与B就是好友了,如果A只是订阅了B,B没有订阅A,那么我们即便说A与B两者不是忘年交,当然矣,我于事实上过程被整好友添加的逻辑还是比较多之,这里要了解A与B相互订阅(openfire服务器遭到订阅状态吧both,当然矣,订阅状态为产生from和to,这样的为算是好友.具体情况后面会详细说明),那么A与B就是忘年交这一个逻辑即可.

</br>

②Install-Package MySql.Data -Version
6.8.8

好友列表获取流程.


当用户登录成功以后,我们开的最为重点的一个模块就是加载好友列表模块.那么好友加载模块的总体流程是哪些的呢?我们事先押一个SDChat好友列表的流程图,帮助我们耳熟能详好友列表在实际上过程被哪些呈现的.(图片或看不清楚,请自行下载查看,谢谢.)

</br>

知音服务器数据获得代码有

XMPPFramework中好友列表的管住核心类是XMPPRoster,这个仿佛可据此来对好友的信获得,添加,删除等操作.在SDChat中,我们拿XMPPRoster声明为SDXmppManager的一个性能对象,并且于初始化过程遭到激活好友模块.代码如下所示.(说明:XMPPRosterCoreDataStorage对象下存储好友数据的.)

self.rosterCoreDataStorage= [XMPPRosterCoreDataStorage sharedInstance];

self.roster = [[XMPPRoster alloc]initWithRosterStorage:self.rosterCoreDataStorage dispatchQueue:dispatch_get_global_queue(0, 0)];

//激活roster
[self.roster activate:self.stream];

骨子里好友获取是产生少数种方式的,骚栋使用的凡代理方得到好友节点的.由于代理方默认的凡当报到成功之后默认就会调用获取好友节点,但是自己举行页面的当儿要调剂一下密友节点获取之空子,所以,我就是管XMPPRoster的自动获取好友节点功能关闭了.当然矣,你可以动用电动获得取.这个用依据实际情形只要早晚,实现代码如下所示.

self.roster.autoFetchRoster = NO;

这么在咱们登录就以后,我们用在- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender本条方式中手动调起获得好友的方法.调起计吧杀简短,只待一行代码就可以.

[[SDXmppManager defaulManager].roster fetchRoster];

当我们调起了收获好友的措施后,我们要以以维系人列表(SDContactsVC)这个控制器中先行安装XMPPRoster目标的代理.我是在初始化就安装了代理对象.

[[SDXmppManager defaulManager].roster addDelegate:self delegateQueue:dispatch_get_main_queue()];

安装好之后代理方其实总共是有三独底,三个代理调取的实际上分别是颇具好友节点获取开始,每一个密友节点获取到之当儿,所有好友节点获取成功之后,我们可以依据实际状况来进展不同的操作.比如我们于取开始前初始化好友节点数组,获取了刷新页面等等,具体的老三个代理方如下所示.

//开始获取好友节点列表的时候
-(void)xmppRosterDidBeginPopulating:(XMPPRoster *)sender;

//获取每一个好友节点的时候
-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item;

//结束获取好友节点列表的时候
-(void)xmppRosterDidEndPopulating:(XMPPRoster *)sender;

立马是自偏偏行使了后边的星星个代理方,这是发生来头的,因为自己的知音节点数组([SDUser defaulUser].contactsArray)不需各级一样不好得到都进展翻新,而且这三个代理方在其实行使过程中,自动调取的次数多,比如添加完好友或者去完好友都能自行调取这三单代理方,为了不必要之难为,所以自己只是用了后的一定量个代理方法.还是那么句话,大家可因自己之实际上情况自行调用不同的代办方法.

俺们事先押一下SDChat中在-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item;骚栋都召开了哪的操作.首先,我们获得到每一个密友节点item,然后我们先行判断item节点的订阅信息subscription的价值,我们要之挚友是两者互为订阅,也便是”subscription”属性也”both”、”from”、”to”才是我们要之好友节点.所以符合当下三栽状态的还是我们得之莫逆之交节点,所以if的淘标准虽出来了,如下代码所示.其他订阅类型不同的节点我们后面会说及现实的情况.

if ([[[item attributeForName:@"subscription"] stringValue] isEqualToString:@"both"]||[[[item attributeForName:@"subscription"] stringValue] isEqualToString:@"from"]||[[[item attributeForName:@"subscription"] stringValue] isEqualToString:@"to"]) {

}

每当罗好以后,我们要举行的事情就是得到item节点的JID信息了,这里我们就待两行代码就可完成了.

NSString *SJid = [[item attributeForName:@"jid"] stringValue];

XMPPJID *jid = [XMPPJID jidWithString:SJid];

凭是首界面上出示好友的JID信息,还是晚显示电子名片信息,我们且亟待事先周历好友节点数组([SDUser defaulUser].contactsArray)判断数组中是否已存在拖欠好友信息了.这样做的原由是坐-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item;这代理方恐怕针对一个好友节点获取多次,如果我们无开展选择性的丰富的话,数组可能会见油然而生好友重复的情景之,所以我们用先判断是否存在拖欠好友信息,具体代码如下所示.(关于isDeleteFriend布尔值的留存的义,当我们抹好友的下,订阅信息subscription的价值可能连无是”remove”,有或是”both”,所有我们这边需要加以一个布尔值,后面的删减好友,我们会详细说明的.)

BOOL isExist = NO;

for (SDContactModel *contact in self.user.contactsArray) {

       if ([contact.jid.user isEqualToString:jid.user]) {

            isExist = YES;

          }
}         

判断了是否留存好友信息后,我们就算可以根据isExist这个布尔值来判断了是否要增补加多少了,添加数码经过如下代码所示,这里我是赢得了挚友的片子信息进行的丰富,前期的口舌可一直上加JID.

if (!isExist) {
    //添加数据
    XMPPvCardTemp *vCard =  [[SDXmppManager defaulManager].vCardTempModule vCardTempForJID:jid shouldFetch:YES];

    SDContactModel *contact =[[SDContactModel alloc]init];
    contact.jid = jid;
    contact.vCard =vCard;
    contact.isAvailable = NO;

    [self.user.contactsArray addObject:contact];

}

地方就是由服务器获取到相知数据的骨干流程了.

</br>

好友数据本地整理代码有

当我们收获好友数据形成以后,我们连无是直接表现到页面及,我们得针对好友数据进行规整然后还展现到界面的上.我们经过-(void)xmppRosterDidEndPopulating:(XMPPRoster *)sender;是代理方来调取我们的相知数据整理方法-(void)networkingWithContactsArray;.

-(void)xmppRosterDidEndPopulating:(XMPPRoster *)sender{

    [self networkingWithContactsArray];

}

SDChat的挚友界面是近乎于微信的密友界面的,是分组展示的.所以,数据存储的圆思路是,列表的数据源是储存于一个字典当中,我们管首字母相同之JID或者是用户称存储于一个数组当中.每个key是各一个JID的首字母大写(或者是用户称的首字母大写).因为字典是无序的,那么什么样好有序的排列呢?我们要树立另外一个数组作为排序数组,同时为从在索引数组的作用.我们拿字典中持有的Key放入数组中,然后排序,数据提取过程被我们一味需要依据数组的排列顺序拿取即可.示意图如下所示.

那我们看一下事实上代码过程遭到,对于字典的数据增长整理部分,首先我们而初始化字典对象,然后我们遍历好友节点数组([SDUser defaulUser].contactsArray),取出我们用排序的各一个生死攸关字符串(不管是JID还是用户称).我们调用-(NSString *)transform:(NSString *)chinese是主意回去首字母并且充分写.在斯法中我们发几乎种植情景要处理,一栽是得字符串失败,也就是说传入的凡一个nil值,我们一直归
“#”
,另外一栽是设首字母是数字,那么我们为是亟需返回”#”的.所以这样回去首字母所使用到之方总共就产生矣三独,两独用来判定是否是几度组,一个尽管是截取并且开展字母大写的操作.三只法子如下所示.

//截取首字母并且大写
-(NSString *)transform:(NSString *)chinese{

    if (chinese == nil ||[chinese isEqualToString:@""]) {

        return @"#";

    }

    NSMutableString *pinyin = [chinese mutableCopy];
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformMandarinLatin, NO);
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformStripCombiningMarks, NO);

    NSString *subString = [[pinyin uppercaseString] substringWithRange:NSMakeRange(0, 1)];

    if ([self isPureInt:subString] || [self isPureFloat:subString]) {

        return  @"#";
    }

    return subString;
}

//判断是否为整型:
- (BOOL)isPureInt:(NSString*)string{
    NSScanner* scan = [NSScanner scannerWithString:string];
    int val;
    return [scan scanInt:&val] && [scan isAtEnd];
}
//判断是否为浮点型:
- (BOOL)isPureFloat:(NSString*)string{
    NSScanner* scan = [NSScanner scannerWithString:string];
    float val;
    return[scan scanFloat:&val] && [scan isAtEnd];
}

这就是说通过返回首字母,我们要看清一下脚下之字典对象被是不是就是了改分组的高频组,如果存在,那么直接存储,如果非设有,那么初始化一个数组之后,以首字母为Key,空数组为Value保存到字典中,然后再度将多少存储到数组中失去.具体代码如下所示.

if (self.contactsPinyinDic[firstWord] ==nil) {

    //如果联系人字典数组中没有该分组,那么就初始化一个分组数组,然后存储.
    NSMutableArray *sectionArray =[NSMutableArray  arrayWithCapacity:16];

    [sectionArray addObject:contact];

    [self.contactsPinyinDic setValue:sectionArray forKey:firstWord];

}else{

    NSMutableArray *sectionArray =self.contactsPinyinDic[firstWord];

    [sectionArray addObject:contact];

}

长完成以后,我们就算得对索引数组进行操作了,首先我们要先初始化我们的索引数组,初始化的进程遭到,我们便管持有的key值添加至我们的数组当中去.然后我们需要加上一个空字符串@"",这是以吃”新的心上人”那个分组做准备的.代码如下所示.

self.indexArray = [NSMutableArray arrayWithArray:self.contactsPinyinDic.allKeys];
[self.indexArray addObject:@""];//添加一个空的字符串,用于菜单分组

然后,我们对索引数组进行遍历排序操作.

    for (int i = 0; i<self.indexArray.count; i++) {

        for (int j = 0; j<i; j++) {

            if (self.indexArray[j]>self.indexArray[i]) {

                NSString *objString = self.indexArray[j];
                self.indexArray[j] =  self.indexArray[i];
                self.indexArray[i] = objString;

            }
        }
    }

万一有”#”,为了界面的好看,我们拿”#”放在索引数组的末梢一号,然后,我们就是刷新我们的页面就可.

//索引数组移动#号到最后.
if ([self isIncludeWithJing]) {

    [self.indexArray removeObject:@"#"];

    [self.indexArray addObject:@"#"];
}

[self.contactsList reloadData];

这般于tableView的数据源方法被,分组个数为索引数组的要素个数self.indexArray.count;每一个section中元素的个数(除了一个分组)都是吗字典中对应之每一个value数组的只数.

然后,我们不怕可做出开始的界面的师来了.当然了,这样的镜头需要我们做过多行事之,也是咱下一样首博客所假设说交之,电子名片的实现.

</br>

③Install-Package MySql.Data.Entity
-Version 6.8.8

结束


SDChat中之知心人获取的逻辑和代办方就是说交这里了,这里自己只要先期声明一下,SDChat中或者还存在Bug,如果产生另外问题,欢迎联系骚栋,谢谢.接下来的平等篇自觉得应该先行把XMPPFramework电子名片的实现说一下,XMPPFramework我看太坑的就是是长好友这同片了,逻辑比较多,准备以第五首被展开讲解说明.希望大家不断关注~最后把SDChat的传递门送给大家.大家可比着Demo来拘禁本篇博客.

3.App.Config配置文件里丰富:

–>SDChat传送门🚪

</br>

<connectionStrings>
<add name="connStr" connectionString="data source=127.0.0.1;user 
id=root;password=123456;database=sqltest;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>

4.依次新建Person实体类,PersonConfig类,详细代码:

public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

 

class PersonConfig : EntityTypeConfiguration<Person>
    {
        public PersonConfig()
        {
            this.ToTable("T_Persons");
        }
    }

5.新建MyContext类,详细代码(注意:如果非以看似上方做DBConfigurationType标记的言辞会以末操作update-database时错,别忘)

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
    class MyContext : DbContext
    {
        public MyContext()
            : base("name=connStr")//name对应配置文件里的连接字符串name属性
        {

        }
        public DbSet<Person> Persons { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
        }
    }

6.继往开来于程序包管理器控制高运行命令Enable-Migrations
-force,成功后拿会晤油然而生如图所示信息:

图片 1

小心:此时在类型下会自动生成文件夹和一个近乎,如图所示:

图片 2

7.开辟Configuration.cs,将AutomaticMigrationsEnabled的价修改为true,并且以先后包管理器控制高运行命令update-database
-force,成功后拿会面世如图所示信息:

图片 3

在意:没当MyContext类上方标记DBConfigurationType害得自身当时无异步浪费了某些独钟头,会提示No
MigrationSqlGenerator found for provider ‘MySql.Data.MySqlClient’. Use
the SetSqlGenerator method in the target migrations configuration class
to register additional SQL generators.

8.现在来测试效果。目前mysql里从未名字给sqltest的数据库是,CodeFirst是通过代码来动生成数据库的。主函数代码如下:

using (MyContext ctx = new MyContext())
            {
                Person per1 = new Person { Name = "per1", Age = 12 };
                Person per2 = new Person { Name = "per2", Age = 17 };
                Person per3 = new Person { Name = "per3", Age = 19 };
                ctx.Persons.Add(per1);
                ctx.Persons.Add(per2);
                ctx.Persons.Add(per3);
                ctx.SaveChanges();
                Console.WriteLine("添加成功");
            }
            Console.ReadKey();

9.运行后若成功,刷新Navicat for
MySQL的数据库列表可以窥见新转变的数据库:

图片 4

瞩目:①自动生成了__migrationhistory表说明配置非常成功。②PersonConfig.cs里的this.ToTable(“T_Persons”);影响实体类映射成功后底表名。③默认Id字段为主键并且自增,因此不欲手动为Id属性赋值。

 

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注