Magicshui's Blog

Magicshui on Programming && Life

git,哥也开始整这玩意了

因为准备在dotask做完以后就转向python以及linux,因此也想顺便把svn抛弃试下git.不像是微软那么财大气粗,提供免费git服务的站点貌似不多,这里大家推荐使用github,不过你只能免费想有300M的仓库空间,对于一般的小项目是足够了~貌似国内没有专门的服务站点,希望有人能够弥补空白~

捕123

对于git,简单的说就是一个版本控制系统,是linux的开发者牵起的项目,但是不同于svn,这个东西没有中心,也就是说是分布式的版本控制。对于各个操作系统兼容性良好,不过还是xunix下表现最佳。

如果首次使用,还是倾向于使用GUI界面管理,但是这不是学习此类系统的最佳途径,所以尽量抛弃GUI,使用bash来进行管理更新吧~对于github,你可以使用ssh来做链接,但是你需要一个key来做通行证,这么没有直接说明,所以,新手会翻迷糊,我就是折腾了半天,还好有教程指导:参见这里

其中,最后的复制key不是那个一堆:的字符,而是你的id_rsa.pub文件,这个可以查找下,在windows中默认在c:/user/yourname/.ssh/id_rsa.pub中~剩下的就照只是走~

因为git这东西会有一堆新的概念需要学习,所以,暂时说到了这。以后,将会以一个实际的项目作为说明来进行学习,当然是使用python作为开发工具,希望能够顺利把东西开发出来,同时能够学习到git的神奇之处吧~

MVC步步深入:12

对于DbContext的继承是EF的核心之一。它主要是包含了三个方面的内容:

1 如何连接数据库

2 确定上下文(code first还是Database First等)

3 额外的高级设置

当然,最基础的就是如何连接数据库,下面主要说三种方式:

namespace Magic.Unicorn
{
    public class UnicornsContext : DbContext
    {
        public UnicornsContext()
        // C# will call base class parameterless constructor by default
        {
        }
    }
}

这种方式程序将会自动建立并且将数据库并名为Magic.Unicorn.UnicornsContext,而数据库德连接是自动寻找本地的SQL Server Express,所以如果你没有安装,自然会报错。

public class UnicornsContext : DbContext
{
    public UnicornsContext()
        : base("UnicornsDatabase")
    {
    }
}

这一种遇上变得有不同的地方,但是差别不到,他将会使用UnicornsDatabase作为数据库名。


  
    
  

这是采用的配置文件,比Express可控性强点。如果你的类和上边的name同名,就会自动连接。

public class UnicornsContext : DbContext
{
    public UnicornsContext()
        : base("UnicornsCEDatabase")
    {
    }
}

但如果不是同名的话必须要设置,base(“name=UnicornsCEDatabase”)中name=是可选项。


  
    
  

看起来和codefirst很像,不同的是这个你已经有了数据库,也就是说是Database/Model First,因此,数据库连接参数必然要详细点。而类中设置的方法相同,

public class NorthwindContext : DbContext
{
    public NorthwindContext()
        : base("name=Northwind_Entities")
    {
    }
}

对于DbContext构造函数,你能做的不只是这些,比如:

1 使用ModelBuilder类来不实例化建立Code First模型

2 直接传递给DbContext一个连接参数

3 使用已经存在的DbConnection对象,并将它传递给DbContext

4 将ObjectContext传递给DbContext

下面就是使用DbSet属性来定义DbContext驱动内容:

public class UnicornsContext : DbContext
{
    public DbSet Unicorns { get; set; }
    public DbSet
 Princesses { get; set; }
    public DbSet LadiesInWaiting { get; set; }
    public DbSet Castles { get; set; }
}

其中的属性将会自动Map到数据库并且建立相应的表。

不过你可以同样适用IDbSet属性:

public class UnicornsContext : DbContext
{
    public IDbSet Unicorns { get; set; }
    public IDbSet
 Princesses { get; set; }
    public IDbSet LadiesInWaiting { get; set; }
    public IDbSet Castles { get; set; }
}

这个主要是使用接口,作用就是接口的作用~呜哈哈眨眼

如果不想暴露属性,就可以设置为只读:

public class UnicornsContext : DbContext
{
    public IDbSet Unicorns
    {
        get { return Set(); }
    }

    public IDbSet
 Princesses
    {
        get { return Set
(); }
    }

    public IDbSet LadiesInWaiting
    {
        get { return Set(); }
    }

    public IDbSet Castles
    {
        get { return Set(); }
    }
}

当数据库建立好以后,我们就可以尝试来做一些查询,什么?SQL,好吧,这个不符合本系列的主题,因为我们将会使用一些面向对象的查询方式:

using (var context = new UnicornsContext())
{
    // Query for all unicorns with names starting with B
    var unicorns = from u in context.Unicorns
                   where u.Name.StartsWith("B")
                   select u;

    // Query for the unicorn named Binky
    var binky = context.Unicorns
                    .Where(u => u.Name == "Binky")
                    .FirstOrDefault();
}

这个代码使用的明显是LINQ的语法,你能够这样写的前提是DbSet或是IDbSet继承了IQueryable。这个你不用操心,因为他本来就是继承的。

我们可以同样适用主键做查询,如果你的查询在当前的Context中没有查询到才会下一步转到database进行查询,算不算是减少了对数据库的压力呢?查找和查询是不同的,额~这一点貌似很不通顺,不过有两点需要记住:

1 在实体没有被查询到的时候才会进入数据库

2 Find将返回被标记为Added状态的实体,但是有时候他还没有被更新到数据库

下面就是适用查找的例子:

using (var context = new UnicornsContext())
{
    // Will hit the database
    var unicorn = context.Unicorns.Find(3);

    // Will return the same instance without hitting the database
    var unicornAgain = context.Unicorns.Find(3);

    context.Unicorns.Add(new Unicorn { Id = -1 });

    // Will find the new unicorn even though it does not exist in the database
    var newUnicorn = context.Unicorns.Find(-1);

    // Will find a castle which has a string primary key
    var castle = context.Castles.Find("The EF Castle");
}

在前面我们看到了为LadyInWaiting实体标记了PrincessId以及CastleName属性,这算是复合属性。

下面的查找就相当于是查找PrincessId=3并且CastleName=’…’的实体:

using (var context = new UnicornsContext())
{
    var lady = context.LadiesInWaiting.Find(3, "The EF Castle");
}

可能一会好奇什么是实体的状态,下面我们就说明关于实体状态的东西。

一般来说,EF中包含了如下的集中状态:

Added 数据库中没有,添加到数据库
Unchanged 数据库中存有,没有变化
Modified 数据库中存有,属性值被修改
Deleted 被上下文跟踪到,数据库中还存有
Detached 没有被上下文跟踪到

在DbContext中我们通常会用到SaveChanges,他在对以下的实体作用时有些不同:

Unchaged 实体没有被触及
Added实体将会插入数据库,返回以后成为Unchanged实体
Modified实体在数据库中更新成为Unchanged实体
Deleted实体从数据库中删除,然后成为Detached

下面演示如何添加实体到Context中:

第一种方式,使用的比较普遍:

using (var context = new UnicornsContext())
{
    var unicorn = new Unicorn { Name = "Franky", PrincessId = 1};
    context.Unicorns.Add(unicorn);
    context.SaveChanges();
}

第二种方式就是通过状态来进行:

using (var context = new UnicornsContext())
{
    var unicorn = new Unicorn { Name = "Franky", PrincessId = 1};
    context.Entry(unicorn).State = EntityState.Added;
    context.SaveChanges();
}

附加一个已经存在的实体到上下文的作用是数据库中存在但是没有被上下文跟踪到,就可以使用如下的方式进行:

var existingUnicorn = GetMyExistingUnicorn();

using (var context = new UnicornsContext())
{
    context.Unicorns.Attach(existingUnicorn);

    // Do some more work... 

    context.SaveChanges();
}

另一种方式就是:

var existingUnicorn = GetMyExistingUnicorn();

using (var context = new UnicornsContext())
{
    context.Entry(existingUnicorn).State = EntityState.Unchanged;

    // Do some more work... 

    context.SaveChanges();
}

而对于存在但是修改过的实体,我们可以使用状态来附加到上下文:

var existingUnicorn = GetMyExistingUnicorn();

using (var context = new UnicornsContext())
{
    context.Entry(existingUnicorn).State = EntityState.Modified;

    context.SaveChanges();
}

这样实体的属性值都会被自动送到数据库中,但是有一点,他所引用的其他实体将不会被跟踪到,所以需要小心别出问题,造成数据不一致了~

在写程序的时候我们经常会需要判断一个实体是否是新加入或是更新过的,通过EF我们能够利用状态来进行判断进而进行其他相关操作:

public void InsertOrUpdate(DbContext context, Unicorn unicorn)
{
    context.Entry(unicorn).State = unicorn.Id == 0 ?
                                   EntityState.Added :
                                   EntityState.Modified;
    context.SaveChanges();
}

为牛B起来需要做这些准备

不想就这么样子一直下去,所以,要为未来积累!

为自己列的ToDo,希望能够完成,同时也希望能够在暑期的时候找到一个好的实习单位!

1 理论扎实,术业专攻

2 Ubuntu至少要占据电脑使用时间的60%

3 python必须要学习,c必须能够在linux下使用

4 vim不再强迫自己,但是如果想成功,就不得不

5 编译原理、计算机组成原理什么的,还是要读一读

6 懂设计模式,并遵循

7 管理学的东西,多多益善

8 读史

9 起码有一些真正喜欢的歌手吧

10 发起一个开源项目,并且让至少100个人收益,至少5人参与到其中,非盈利为目的

12 用英文开始写东西,尽管现在对我来说有点困难

13 参加到一个开源项目中,活跃下