EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)

本篇原文地址:Creating a More Complex Data Model

本篇讲的比较碎,很多内容本人认为并不是EF的内容,既然原文讲了,那就按照原文来学习吧。。。

第1步:通过属性来定制化数据模型

通过 DataType Attribute来定义数据模型字段属性:

先加申明 using System.ComponentModel.DataAnnotations;

然后为需要定义属性的字段加上属性:(例如EnrollmentDate 加上日期DataType,以及显示格式的属性)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace EFTest.Models
{
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

DataType 枚举可以通过 DataType Enumeration链接来查看;主要有用的是:Date,Time,EmailAddress,Password等;
通过DataType定义的数据属性,在应用中得到特殊的数据处理功能,比如Email的话,就在显示的时候自动变为点击发Email的Link;如果Date的话,会在前端自动显示为一个日期输入选择框(在HTML5的情况下);

但是DataType不提供验证功能,并且也不特别指定显示格式,默认的显示格式基于服务器的CultureInfo

DispalyFormat属性定义就是用来明确定义显示格式;

DisplayFormat可以单独使用,但建议是配合DataType一起使用,配合使用会有以下优点:

1、HTML5支持的浏览器可以根据DataType做出一些特定的调整及显示(比如会显示计算器、日期输入框、Email地址链接等等)

2、默认情况下,浏览器会根据客户端计算机的本地化显示设置来进行渲染(比如本地化的日期时间格式)

3、DataType属性可以让MVC选择正确的字段类型去渲染数据,DisplayFormat使用字符串类型模板;

更多的信息可以参考:MVC 5 Introduction: Examining the Edit Methods and Edit View

通过StringLength 属性定义长度

可以通过StringLength这个属性来定义一个字段的最长长度,并且可以设置出现错误后应该提供的错误信息;

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace EFTest.Models
{
public class Student
{
public int ID { get; set; }
[StringLength()]
public string LastName { get; set; }
[StringLength(, ErrorMessage = "First name 不可以超过50个字符.")]
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

比如设定LastName、FirstMidName最长只能50个字符,并且在FirstMidName输入超过50个字符的时候提示相应错误;
另外,StringLength属性定义不能防止用户输入空格,所以可以通过RegularExpression来进行限制:

[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]

以上这个属性定义,限制首字母为大写,后面也必须为字母;

PS: MaxLength属性定义也能定义字段最大长度,但是并不提供客户端验证。

这个时候如果直接运行应用,并点击Students页面,就会有以下错误:

说明数据模型变了,数据库也需要先升级才可以;

先在PM控制台执行 add-migration MaxLengthOnNames

会自动创建一个带时间戳的数据升级文件;然后在PM控制台继续输入:update-database

完成后,就可以再次尝试进入应用的Student页面,并点击Create进入新建页面:

Column 属性定义:当一些特定情况下,希望数据库里的字段名采用一个约定格式名,而模型中是另一个名称,则需要通过Column来强制换个名字:

首先,添加申明:using System.ComponentModel.DataAnnotations.Schema;

然后用[Column("NewColumnName")] 定义数据库中的列名:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class Student
{
public int ID { get; set; }
[StringLength()]
public string LastName { get; set; }
[StringLength(, ErrorMessage = "First name 不可以超过50个字符.")]
[Column("FirstName")]
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

当然,在做了这个改动后,需要今天数据库升级操作:

在PM控制台输入以下命令:
  add-migration ColumnFirstName
  update-database

更新后,列名变了,并且DataType从nvarchar(MAX) 变为 nvarchar(50):

PS: 这个操作可以通过 Fluent API 来完成,后面也会提及到。

将Student模型变更为以下完整版本:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class Student
{
public int ID { get; set; }
[Required]
[StringLength()]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[StringLength(, ErrorMessage = "First name 不可超过50个字符.")]
[Column("FirstName")]
[Display(Name = "First Name")]
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Enrollment Date")]
public DateTime EnrollmentDate { get; set; } [Display(Name = "Full Name")]
public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
} public virtual ICollection<Enrollment> Enrollments { get; set; }
} }

[Required]对于值类型的是不需要的,例如int , DateTime, double, float ,因为这些值本身是不可以为空NULL的;

对于字符串类型的属性(property),可以通过设置最小长度来代替[Required]:

[Display(Name = "Last Name")]
[StringLength(, MinimumLength=)]
public string LastName { get; set; }

Display定义在显示View的时候,对应该属性(property)的输入框标题内容;

另外,FullName是一个计算出来的属性(property),所以只有get ,没有set ,这样在数据库里是不会增加 FullName这个列的;

新建Instructor模型:(和Student 模型差不多)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class Instructor
{
public int ID { get; set; } [Required]
[Display(Name = "Last Name")]
[StringLength()]
public string LastName { get; set; } [Required]
[Column("FirstName")]
[Display(Name = "First Name")]
[StringLength()]
public string FirstMidName { get; set; } [DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Hire Date")]
public DateTime HireDate { get; set; } [Display(Name = "Full Name")]
public string FullName
{
get { return LastName + ", " + FirstMidName; }
} public virtual ICollection<Course> Courses { get; set; }
public virtual OfficeAssignment OfficeAssignment { get; set; }
} }

当然也可以简化属性定义为一行:(通过逗号来分割)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class Instructor
{
public int ID { get; set; } [Display(Name = "Last Name"), StringLength(, MinimumLength = )]
public string LastName { get; set; } [Column("FirstName"), Display(Name = "First Name"), StringLength(, MinimumLength = )]
public string FirstMidName { get; set; } [DataType(DataType.Date), Display(Name = "Hire Date"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime HireDate { get; set; } [Display(Name = "Full Name")]
public string FullName
{
get { return LastName + ", " + FirstMidName; }
} public virtual ICollection<Course> Courses { get; set; }
public virtual OfficeAssignment OfficeAssignment { get; set; } } }

在Instructor模型中 Courses 和 OfficeAssignment为导航属性,采用virtual来定义为延迟加载;
Instructor对应Courses 是1对n ,所以采用ICollection<T>来表示;

Instructor对应OfficeAssignment是1对1,所以直接采用OfficeAssignment来定义;

新建OfficeAssignment模型:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class OfficeAssignment
{
[Key]
[ForeignKey("Instructor")]
public int InstructorID { get; set; }
[StringLength()]
[Display(Name = "Office Location")]
public string Location { get; set; } public virtual Instructor Instructor { get; set; }
} }

Instructor对应OfficeAssignment是1对1或者 1对0,即OfficeAssignment表中的InstructorID一定是在Instructor存在这个ID的;

所以对于OfficeAssignment InstructorID需要设置为主键,并且要定义为从Instructor ID来的外键;

修改Course模型

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Number")]
public int CourseID { get; set; } [StringLength(, MinimumLength = )]
public string Title { get; set; } [Range(, )]
public int Credits { get; set; } public int DepartmentID { get; set; } public virtual Department Department { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<Instructor> Instructors { get; set; }
} }

新建Department模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFTest.Models
{
public class Department
{
public int DepartmentID { get; set; } [StringLength(, MinimumLength = )]
public string Name { get; set; } [DataType(DataType.Currency)]
[Column(TypeName = "money")]
public decimal Budget { get; set; } [DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Start Date")]
public DateTime StartDate { get; set; } public int? InstructorID { get; set; } public virtual Instructor Administrator { get; set; }
public virtual ICollection<Course> Courses { get; set; }
} }

最后希望的模型定义图:

做些总结汇总:

1、模型中Properties如果名称为ID或者是类名+ID,则EF会自动将其变为主键;

2、如果主键为int型,默认会定义为数据库自增长的类型,除非用 [DatabaseGenerated(DatabaseGeneratedOption.None)] 来明确告知不要;

3、如果是1对1或0的对应关系,需要明确用[ForeignKey("XXXX")]来告知EF哪个是主表哪个是子表,不然会报异常;

4、如果是多对1或0的对应关系,如果Properties是值类型,则需要用 问号 来定义可以为空;

5、默认情况下,EF是开启联级删除(cascade delete),那么如果外键导致的联级删除出现多个

例如:    A -> B 是 1对多,   A -> C 也是 1对多,  B 和 C 是多对多, 那么要删除 一个A,就需要联级删除先删除 B 和 C ,而要删除B 和 C 就要先删除 B 和 C 连接对应;

这样就有两条路都到删除 B 和 C 的连接关系,这个是数据库所不允许的;

那么只有两种方式:

a) fluent API来申明关闭这个A的cascade delete;

b) 把A -> B设置为 0,1对多,或者  A -> C 设置为 0,1对多, 即删除A时,不是删除B,而是把B里涉及到A的外键列值设置为NULL。

6、如果是多对多的关系,则EF会自动新建一个表来存储多对多的关系;

在上下文类中通过Fluent API来定义复杂模型关系及一些设定

在上下文类中增加定义所有的实体,并通过Fluent API来定义一些设定;

Fluent API可以用来设定绝大部分的模型关系及定义,但是也有一些不可以用Fluent API来设定,比如 MinimumLength

因为MinimumLength 不会对数据库结构产生影响,而只是对客户端验证起作用;

有点程序员比较喜欢用Fluent API,这样模型定义看起来“干净”很多,也可以用属性定义和Fluent API混合起来使用;

以下的Fluent API定义了多对多的连接关系所采用的表名:

using EFTest.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions; namespace EFTest.DAL
{
public class SchoolContext : DbContext
{
public SchoolContext() : base("SchoolContext")
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Instructor> Instructors { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<OfficeAssignment> OfficeAssignments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Course>()
.HasMany(c => c.Instructors).WithMany(i => i.Courses)
.Map(t => t.MapLeftKey("CourseID")
.MapRightKey("InstructorID")
.ToTable("CourseInstructor"));
}
}
}

初始化种子数据

模型调整好后,在Migrations\Configuration.cs文件中Seed方法中放入测试种子数据:

namespace EFTest.Migrations
{
using DAL;
using Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq; internal sealed class Configuration : DbMigrationsConfiguration<EFTest.DAL.SchoolContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
} protected override void Seed(EFTest.DAL.SchoolContext context)
{
var students = new List<Student>
{
new Student { FirstMidName = "Carson", LastName = "Alexander",
EnrollmentDate = DateTime.Parse("2010-09-01") },
new Student { FirstMidName = "Meredith", LastName = "Alonso",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Arturo", LastName = "Anand",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Gytis", LastName = "Barzdukas",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Yan", LastName = "Li",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Peggy", LastName = "Justice",
EnrollmentDate = DateTime.Parse("2011-09-01") },
new Student { FirstMidName = "Laura", LastName = "Norman",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Nino", LastName = "Olivetto",
EnrollmentDate = DateTime.Parse("2005-09-01") }
}; students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
context.SaveChanges(); var instructors = new List<Instructor>
{
new Instructor { FirstMidName = "Kim", LastName = "Abercrombie",
HireDate = DateTime.Parse("1995-03-11") },
new Instructor { FirstMidName = "Fadi", LastName = "Fakhouri",
HireDate = DateTime.Parse("2002-07-06") },
new Instructor { FirstMidName = "Roger", LastName = "Harui",
HireDate = DateTime.Parse("1998-07-01") },
new Instructor { FirstMidName = "Candace", LastName = "Kapoor",
HireDate = DateTime.Parse("2001-01-15") },
new Instructor { FirstMidName = "Roger", LastName = "Zheng",
HireDate = DateTime.Parse("2004-02-12") }
};
instructors.ForEach(s => context.Instructors.AddOrUpdate(p => p.LastName, s));
context.SaveChanges(); var departments = new List<Department>
{
new Department { Name = "English", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Abercrombie").ID },
new Department { Name = "Mathematics", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Fakhouri").ID },
new Department { Name = "Engineering", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Harui").ID },
new Department { Name = "Economics", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Kapoor").ID }
};
departments.ForEach(s => context.Departments.AddOrUpdate(p => p.Name, s));
context.SaveChanges(); var courses = new List<Course>
{
new Course {CourseID = , Title = "Chemistry", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Engineering").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Microeconomics", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Macroeconomics", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Calculus", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Trigonometry", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Composition", Credits = ,
DepartmentID = departments.Single( s => s.Name == "English").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Literature", Credits = ,
DepartmentID = departments.Single( s => s.Name == "English").DepartmentID,
Instructors = new List<Instructor>()
},
};
courses.ForEach(s => context.Courses.AddOrUpdate(p => p.CourseID, s));
context.SaveChanges(); var officeAssignments = new List<OfficeAssignment>
{
new OfficeAssignment {
InstructorID = instructors.Single( i => i.LastName == "Fakhouri").ID,
Location = "Smith 17" },
new OfficeAssignment {
InstructorID = instructors.Single( i => i.LastName == "Harui").ID,
Location = "Gowan 27" },
new OfficeAssignment {
InstructorID = instructors.Single( i => i.LastName == "Kapoor").ID,
Location = "Thompson 304" },
};
officeAssignments.ForEach(s => context.OfficeAssignments.AddOrUpdate(p => p.InstructorID, s));
context.SaveChanges(); AddOrUpdateInstructor(context, "Chemistry", "Kapoor");
AddOrUpdateInstructor(context, "Chemistry", "Harui");
AddOrUpdateInstructor(context, "Microeconomics", "Zheng");
AddOrUpdateInstructor(context, "Macroeconomics", "Zheng"); AddOrUpdateInstructor(context, "Calculus", "Fakhouri");
AddOrUpdateInstructor(context, "Trigonometry", "Harui");
AddOrUpdateInstructor(context, "Composition", "Abercrombie");
AddOrUpdateInstructor(context, "Literature", "Abercrombie"); context.SaveChanges(); var enrollments = new List<Enrollment>
{
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").ID,
CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
Grade = Grade.A
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").ID,
CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID,
Grade = Grade.C
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").ID,
CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").ID,
CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").ID,
CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").ID,
CourseID = courses.Single(c => c.Title == "Composition" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Anand").ID,
CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Anand").ID,
CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Barzdukas").ID,
CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Li").ID,
CourseID = courses.Single(c => c.Title == "Composition").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Justice").ID,
CourseID = courses.Single(c => c.Title == "Literature").CourseID,
Grade = Grade.B
}
}; foreach (Enrollment e in enrollments)
{
var enrollmentInDataBase = context.Enrollments.Where(
s =>
s.Student.ID == e.StudentID &&
s.Course.CourseID == e.CourseID).SingleOrDefault();
if (enrollmentInDataBase == null)
{
context.Enrollments.Add(e);
}
}
context.SaveChanges(); } void AddOrUpdateInstructor(SchoolContext context, string courseTitle, string instructorName)
{
var crs = context.Courses.SingleOrDefault(c => c.Title == courseTitle);
var inst = crs.Instructors.SingleOrDefault(i => i.LastName == instructorName);
if (inst == null)
crs.Instructors.Add(context.Instructors.Single(i => i.LastName == instructorName));
}
}
}

数据库迁移升级

在PM控制台输入: add-Migration ComplexDataModel

这个时候如果直接输入 update-database  会报错,那是因为Course这个表里已经有数据,如果直接加不可为空的列是会报错的;

所以需要在刚刚生成的带时间戳的 XXXXXXXXXXX_ComplexDataModel文件中如下面增加修改部分代码:

即先插入一条临时的Department ,然后把现在所有的Course数据行在增加Department列的时候,指向这个临时Department.

                CreateTable(
"dbo.CourseInstructor",
c => new
{
CourseID = c.Int(nullable: false),
InstructorID = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.CourseID, t.InstructorID })
.ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true)
.ForeignKey("dbo.Instructor", t => t.InstructorID, cascadeDelete: true)
.Index(t => t.CourseID)
.Index(t => t.InstructorID); // Create a department for course to point to.
Sql("INSERT INTO dbo.Department (Name, Budget, StartDate) VALUES ('Temp', 0.00, GETDATE())");
// default value for FK points to department created above.
AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false, defaultValue: 1));
//AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false)); AlterColumn("dbo.Course", "Title", c => c.String(maxLength: ));

最后执行 update-database 即可。

EF6学习笔记(六) 创建复杂的数据模型的更多相关文章

  1. 【EF6学习笔记】目录

    [EF6学习笔记](一)Code First 方式生成数据库及初始化数据库实际操作 [EF6学习笔记](二)操练 CRUD 增删改查 [EF6学习笔记](三)排序.过滤查询及分页 [EF6学习笔记]( ...

  2. ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)

    个人从传统的CS应用开发(WPF)开始转向BS架构应用开发: 先是采用了最容易上手也是最容易搞不清楚状况的WebForm方式入手:到后面就直接抛弃了服务器控件的开发方式,转而采用 普通页面+Ajax+ ...

  3. EF6 学习笔记(五):数据库迁移及部署

    EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 原文地址:Code First Migrations and Deployment 原文主要讲两部分:开发环境下 ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. EF6 学习笔记(二):操练 CRUD 增删改查

    EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...

  6. EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作

    EF6 学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇参考原文地址: Creating an Entity Framework Data Model 说明:学习 ...

  7. Django:学习笔记(2)——创建第一个应用

    Django:学习笔记(2)——创建第一个应用 创建应用 在 Django 中,每一个应用都是一个 Python 包,并且遵循着相同的约定.Django 自带一个工具,可以帮你生成应用的基础目录结构, ...

  8. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  9. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

随机推荐

  1. 199. Spring Boot JNDI:这是虾米?

      [视频&交流平台] àSpringBoot视频:http://t.cn/R3QepWG à SpringCloud视频:http://t.cn/R3QeRZc à Spring Boot源 ...

  2. dubbo实现原理介绍

      一.什么是dubbo Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,     ...

  3. 杰克.多西 twitter创始人 必做清单和不必做清单

    必做清单 活在当下 接受脆弱(Be vulnerable) 只喝柠檬水和红酒 每天 6 组下蹲和俯卧撑 每天跑步 3 英里 每天思考本清单 站直了 打拳击沙袋 10 分钟 跟所有人打招呼 每天 7 小 ...

  4. python 的包的导入

    已经写过一篇包的导入了,最近又遇到了点问题,所以想把这些再搞的明白点就又试了试 代码结构如下 在test目录下,有Admin包,home包,在home下有它的子包foo 各个文件代码如下 admins ...

  5. dto vo

    不过符合规矩的做法是DTO里可以放各种List<VO>,而VO和entity就是一一对应的关系,vo里不能放entity,entity里也不能放vo,vo和entity只存放和数据库完全相 ...

  6. 关于spfa

    关于spfa的一些事宜.... 刚开始学的时候只会跑最短路,代码都是背下来的.以下是背的代码... inline void spfa(int s) { queue<int>q;q.push ...

  7. 2019/1/9 6系列所有装置编号与SIM卡信息抓取

    一.报错:File "G:/station/6系列装置信息明细.py", line 12, in <module>workbook.save(r'.\6系列装置明细表. ...

  8. R语言-图的要素颜色

    1.设置图形要素的颜色 Plot函数中,使用col=参数来决定要素的颜色 如果不指定plot type,颜色加在散点上,如果指定了plot type,例如line,则颜色加在线上 其它函数,例如bar ...

  9. php 二维数组按照某个键排序

    $date = array_column($arr, 'run_date'); //上面得到的结果:array(0=>'2017-11-21',1=>'2017-11-20',3=> ...

  10. html2canvas

    最近公司有个需求,实现html 页面元素转为png图像,这边用了html2canvas来实现.,这里记录一下,避免以后忘了~~ 官网链接: http://html2canvas.hertzen.com ...