using System; using system.ioCollections; using ; using system.ioConfiguration; usi

using S using System.D using System.C using System.L using System.W u提示“system”中不存在类型或命名空间名称‘Ling’(缺少程序集引用吗?)
凌风吓乙28
在解决方案资源管理器中,右击“引用”,点击“添加引用”,在“.NET”标签中选中“System.Data.Linq”,点击确定.
为您推荐:
其他类似问题
扫描下载二维码(是否缺少 using 指令或程序集引用?)该怎么做??_百度知道
(是否缺少 using 指令或程序集引用?)该怎么做??
Spublic partusing System.WebControls.Web.UI.Page{
protected void page_load(object sender.UI;using System.Web.WebParts, EventArgs e)
protected void btnserch_click(object sender, EventArgs e)
protected void formview1_databind(object sender, EventArgs e)
{using System.WebControls“prizeedit”不包含“GridView1”的定义;using System?)该怎么做.Data.UI.Cusing System.HtmlControls.GridView1;using System.Wusing System?.Web.Security.Wusing System.Web?代码;using System.DataBind().UI:using System,并且找不到可接受类型为“prizeedit”的第一个参数的扩展方法“GridView1”(是否缺少 using 指令或程序集引用.Web.Collections.UI
提问者采纳
ASPX文件里没有定义ID为GridView1的元素
怎样去定义?具体一点行吗?
能把你的ASPX页面的源码放上来看一下吗?&body&
&form id=&form1& runat=&server&&
&asp:GridView ID=&GridView1& runat=&server&&
&/asp:GridView&
&/form&&/body&在form中添加一个GridView组件,把ID命名为GridView1
我不知道你要哪个东西,上面有那么多文件,你要哪个??
好吧,你QQ多少?
提问者评价
大哥 ,真的万分感激
其他类似问题
为您推荐:
其他1条回答
或者你把名字搞错了,去设计器里查下重新用代码提示打这句话,是不是this(Page)对象就没有GridView1的成员
程序集的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁求大神帮忙_c#吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:86,634贴子:
求大神帮忙收藏
using Susing System.Cusing System.Cusing System.Dusing System.Lusing System.Wusing System.Web.Susing System.Web.UI;using System.Web.UI.HtmlCusing System.Web.UI.WebCusing System.Web.UI.WebControls.WebPusing System.Xml.Lusing System.Data.SqlCpublic partial class 教师录入成绩页面 : System.Web.UI.Page{
protected void Page_Load(object sender, EventArgs e)
if ((string)Session["userRole"] != "0")
Response.Redirect(Login.aspx);
if (!this.IsPostBack)
Label1=Text="请"+(string )Session ["teacher"]+"老师选择要录入的成绩";
BindDDL();
BindGridView();
//为课程名下拉列绊定数据
private void BindDDl()
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStrings"].ConnectionString);//数据便的连接
string SqlStr="SELECT distinct 课程.课程号,课程.课程名 from 课程 where 教师号='"+ (string)Session["userName"]+"'";
DataSet ds = new DataSet();
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(SqlStr, conn);
da.Fill(ds);
conn.Close();
ddlCourse.DataSource = ds.Tables[0].DefaultV
ddlCourse.DataTextField = "课程名";//下拉列表框每项显示课程的名称
ddlCourse.DataValueField = "课程名";//下拉列表框每项的值为课程编号
ddlCourse.DataBind();
private void BinderGridView()
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStrings"].ConnectionString);
sqlCommand cmd = conn.CreateCommand();
mandText = "select distinct 学生.学生号,姓名,年级,专业 from 学生,选课 ,课程 where 学生.学生号=选课.学生号 and
选课.课程号=课程.课程号 and 课程.课程号
='" + ddlCourse.SelectedValue + "'";
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
GridView1.DataSource =
GridView1.DataBind();
conn.Close();
protected void ddlCourse_SelectedIndexChanged(object sender, EventArgs e)
BindGridView();
protected void ButSC_Click(object sender, EventArgs e)
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStrings1"].ConnectionString);
SqlCommand cmd = conn.CreateCommand();
string courseID=ddlCourse.CreateCommand();
string CourseID = ddlCourse.SelectedV
string stuID;
conn.Open();
for(i=0;i&GridView1.Rows.Ci++)
score=int.Parse(((TextBox)GridView1.Rows[i].FindControl("txtScore")).Text.Trim());
stuID=GridView1.Rows[i].Cells[0].T
mandText = "updata 选课 set 成绩= "+score +" where 学号='"+stuID + "'and 课程号 ='"+courseID + "'";
cmd.ExecuteNonQuery();
conn.Close();
Label2.text="成功录入学生成绩";
//教师任课情况protected void
Button1_Click(object sender, EventArgs e){
Response.Redirect("teacherCourseDetails.aspx");}
//课程选修情况protected void
Button2_Click(object sender, EventArgs e){
Response.Redirect("11学生选课页面.aspx");}
//修改密码protected void
Button3_Click(object sender, EventArgs e){
Response.Redirect("ModifyPwd.aspx");}}为什么总是
说错误1类、结构或接口成员声明中的标记“(”无效D:\WebSite2\老师\10教师录入成绩页面.aspx.cs7815D:\WebSite2\错误1类、结构或接口成员声明中的标记“(”无效D:\WebSite2\老师\10教师录入成绩页面.aspx.cs7815D:\WebSite2\
刘备:军师,此次伐魏你有何妙计?
亲。看置顶帖。发帖规范。
小伙伴们,粉我吧,给我灌水吧
为保持本吧秩序稳定,板面整洁一致!按统一格式发帖,详情看置顶贴,谢谢配合!c#吧欢迎您的常驻!(有关不按规则发帖可能被删除,希望您能配合和理解@)
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或Posts - 73,
Articles - 0,
Comments - 1531
CODING 完美世界...
18:01 by KenshinCui, ... 阅读,
Code First之所以能够让开发人员以一种更加高效、灵活的方式进行数据操作有一个重要的原因在于它的约定配置。现在软件开发越来复杂,大家也都试图将软件设计的越来越灵活,很多内容我们都希望是可配置的,但是过多的配置也会带来很大的工作量,解决这个问题的方法就是约定。对于一些简单的,不太可能经常变化的内容我们以一种约定的方式进行设计。使用过其他ORM框架的朋友可能知道一般ORM都有对应的映射配置文件(一般是一个Xml文件),但是EF并没有。在EF中是以一种约定的方式进行表、列同实体类进行映射的,与此同时为了提高最大的灵活性EF中可以通过Fluent API和Data Annotations两种方式对映射进行灵活配置。
EF默认约定
我们先来看一下EF对于数据类(概念模型,或域模型)的默认约定:
将数据类的类名复数形式作为数据表名称,并且使用“dbo”作为默认架构。
例如定义一个Person数据类,那么将会自动生成“dbo.People”表。
将数据类中的“ID”属性或者“&类名&+ID”作为主键(不区分大小写),并且如果该列为数值类型或者GUID列将作为标识列。
例如在Order类中如果有ID或者OrderID属性将默认作为主键,二者均出现优先使用 “ID”属性。
使用导航属性约束两个表之间的关系,在从表数据类中除了导航属性,推荐定义一个外键属性在从表数据类中(如果不指定将默认生成一个“&主表类名&+&主表类的主键名&”的外键列;此外在主表中推荐定义一个集合从表属性用户导航,当然这个属性不定义也可以正常生成外键关系但是不利于使用),具体规则:“&导航属性名&+&主表的主键属性名&”或者“&主表类名&+&主键属性名&”又或者“&主表的主键属性名&”,其属性名不区分大小写并且如果出现多种匹配按照先后顺序匹配;如果不存在外键属性则外键关系注册为可选的,否则注册为必选项并且此时将设置级联删除关系;如果在从表类中有多个导航属性对应同一个数据类那么需要使用fluent API或者Data Annotations进行手动配置。
例如有一个Order类,主键为OrderID,在OrderDetail类中有一个导航属性Order(Order类型),那么当你定义一个OrderID在OrderDetail中,那么在Order和OrderDetail直接将建立一个级联删除关系。
当EF按照上述规则在数据类中没有找到主键属性时(或者通过fluent API、Data Annotations没有定义)将认为此类为“复杂类型”(对于不了解复杂类型的朋友请点击这里)。
例如在“Person”数据类中有一个“Name”属性,但是数据库中可能将“Name”分为FirstName和LastName存储,此时就可以定义一个Name类,在此类中不定义主键列定义“FirstName”和“LastName”属性,就会在表“dbo.People”中生成“Name_FirstName”和“Name_LastName”列。
EF的默认约定不是一成不变的,我们可以选择移除和修改它,例如EF默认生成数据表时将数据类名的复数形式作为表名,下面的代码就可以移除这个规则:
using System.Collections.G
using System.L
using System.T
using System.Data.E
using CodeFirst.E
using ponentModel.DataAnnotations.S
using System.Data.Entity.ModelConfiguration.C
namespace CodeFirst
public class OrderContext:DbContext
public OrderContext()
: base(&CodeFirstDb&)
Database.SetInitializer&OrderContext&(
new DropCreateDatabaseIfModelChanges&OrderContext&()
public DbSet&Person& Person
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove&PluralizingTableNameConvention&();
这些规则都在“System.Data.Entity.ModelConfiguration.Conventions”命名空间下,可以根据实际情况进行选择。
一般情况下我们是不需要移除默认约定的,我们更多的时候是要修改丰富这些约定,达到对生成规则的更多细节控制。在EF提供了两种方式进行映射配置:Data Annotations和Fluent API。
DataAnnotations
DataAnnotations是ASP.NET WEB中添加的一种验证方式,但是在EF中它又可以对映射关系进行控制,相比较Fluent API使用起来要简单一些。下面我们通过一个例子对DataAnnotations进行说明。在此我们假设有一个“Employee”类用于描述员工信息,一个“Customer”类用于描述客户信息,还有一个“Order”类用于描述订单信息,此外还有一个“Name”复杂类型表示人员姓名。在Order类中有一个属性“Customer”用于描述此订单的客户,它是“Customer”类型;还有一个“DeliverPerson”属性用于描述订单发货人,一个“CheckPerson”属性用户描述订单拣货人,它们都是“Employee”类型。下面是具体代码:
Employee类:
using System.Collections.G
using ponentModel.DataA
using ponentModel.DataAnnotations.S
using System.L
using System.T
namespace CodeFirst.Entities
[Table(&People&,Schema=&Person&)]
public class Employee
public int No
public Name Name
[MinLength(5),MaxLength(30)]
public string Title
[Required]
public DateTime BirthDate
[ConcurrencyCheck]
public string Address
[Column(&Notes&,TypeName=&ntext&,Order=5)]
public string Note
[ponentModel.DataAnnotations.puted)]
public DateTime CreateDate
[NotMapped]
public string PhotoPath
[Timestamp]
public byte[] TimeStamp
[InverseProperty(&DeliverPerson&)]
public List&Order& DeliverOrder
[InverseProperty(&CheckPerson&)]
public List&Order& CheckOrder
Customer类:
using System.Collections.G
using System.L
using System.T
namespace CodeFirst.Entities
public class Customer
public int CustomerID
public string CompanyName
using System.Collections.G
using ponentModel.DataAnnotations.S
using System.L
using System.T
namespace CodeFirst.Entities
[ComplexType]//根据前面我们说的默认约定,不标记为ComplexType只有没有找到ID也会将Name作为一个复杂类型
public class Name
public string FirstName
public string LastName
using System.Collections.G
using ponentModel.DataAnnotations.S
using System.L
using System.T
namespace CodeFirst.Entities
public class Order
public int OrderID
public string OrderTitle
public string CustomerName
public DateTime TransactionDate
public int CustomerNo
[ForeignKey(&CustomerNo&)]
public Customer Customer
public Employee DeliverPerson
public Employee CheckPerson
这是通过Data Annotations配置后EF生成的数据库表结构:
下面解释每个配置的作用
Table:用于指定生成表的表名、架构信息。
Column:用于指定生成数据表的列信息,如列名、数据类型、顺序等。
Key:用于指定任何名称的属性作为主键列并且默认将此列作为标识列(如果不想默认生成标识可以指定“DatabaseGenerated”属性的值为“None”),如果不指定此标记属性,将根据EF默认约定创建主键。如上代码指定“No”为“Employee”的主键。
Required:用户指定非空列,如上面的“BirthDay”创建列之后为“not null”列。
MinLength、MaxLength:指定字段长度(此属性通常可以用户客户端验证),例如上面“Title”定义成了“nvarchar(30)”。
ComplexType:用于标记复杂类型,对于包含复杂类型数据属性的类在生成数据表时复杂类型中每个属性都将作为其中一列。
DatabaseGenerated:用于指定数据库字段生成列,此类EF将不会直接更新。可以指定为计算列、标识列和非数据库生成列(例如给主键列指定此属性为“None”则不会生成标识列)。需要注意的是如果使用Code First字段生成数据库,那么此属性仅仅可以用于byte、timestamp列上,否则请应用在已经存在数据库的情况下,因为Code First无法判定生成具体计算列的公式(至少目前Code First还不支持公式配置)。
NotMapped:用户指定非映射列,标记此属性的列将不会在数据库中生成相应的列,例如上面的“PhotoPath ”没有在数据库中生成具体列,实际使用中它可能是通过其他具体规则得到的。
ConcurrencyCheck:用于进行并发检查,当一个用户A获得实体后通常会与数据库断开,此时如果另一个用户B也获得了实体并进行了修改,那么当A再进行更新时如果进行了“ConcurrencyCheck”标记则会进行并发检查,并根据原始值判断该实体是否存在,如果不存在则抛出异常。
TimeStamp:用于指定时间戳列,一个实体只能有一个TimeStamp列。在EF中TimeStamp是另一种并发控制方式,当EF遇到TimeStamp列会自动配置 “ConcurrencyCheck”及“puted”来控制并发(通常我们推荐使用此方法)。
ForeignKey:用于指定外键列,我们知道按照上面提到的默认约定第三条,当我们在“Order”中定义了“Customer”属性后,如果定义“CustomerID” 属性(当然还有其他形式,大家可以按照声明说的默认约定3进行测试),那么EF会在“Order”表中创建一个“CustomerID”列并建立与“Customer”表的外键关系。但是如果像上面定义“CustomerNo”属性并且不指定“ForeignKey”标记的话将达不到我们的预期,EF将默认创建一个“Customer_CustomerID”列并创建与“Customer”的外键约束,同时创建一个“CustomerNo”列。当然解决的方式大家已经看到了那就是给导航属性“Customer”指定“ForegnKey”标记并且指定外键列为“CustomerNo”(注意虽然在“Customer”中不定义“Order的导航属性”生成的表中也并没用任何问题,但是我们推荐您定义相应的导航属性)。
InverseProperty:用于定义多重外键关系约束。我们在EF中通过导航属性定义主外键关系,但是当主表中有两个外键约束时可能仅仅通过添加相应的导航属性就无法完成了,例如上面“Order”中“DeliverPerson”和“CheckPerson”均为“Employee”类型,按我们的预期当然是在生成“Order”表时生成两个外键列并创建与“Employee”外键约束关系,但是如果没有在“Employee”类的“DeliverOrder”和“CheckOrder”属性上标记 “InverseProperty”属性EF是无法识别这种关系的(具体结果可以看下图),当然解决方式就是在对应导航属性中标记“InverseProperty”并指定对于的列名。
注意:DataAnnotations可以同时在同一个类后者属性上使用多个标记属性,上面的例子中对于每个类或属性只使用了一个单独的标记属性是为了说明起来更加简单;另外声明的例子中同时使用“ConcurrencyCheck”和“TimeStamp”指定了不同的列只是为了演示,一般情况下我们通过其中一种方式即可。
Fluent API
Fluent API一般配置
尽管我们可以通过Data Annotations进行映射关系约定,但是相比较而言Fluent API的功能更加强大,从功能上而言Data Annotations是Fluent API的一个子集, Data Annotations可以实现的功能Fluent API都能实现。下面我们先看一个例子,在这个例子中我们通过Fluent API约定方式实现上面Data Annotations的功能并且包含更多控制:
using System.Collections.G
using System.L
using System.T
using System.Data.E
using CodeFirst.E
using ponentModel.DataAnnotations.S
using System.Data.Entity.ModelConfiguration.C
namespace CodeFirst
public class OrderContext:DbContext
public OrderContext()
: base(&CodeFirstDb&)
Database.SetInitializer&OrderContext&(
new DropCreateDatabaseIfModelChanges&OrderContext&()
public DbSet&Order& Orders
public DbSet&Employee& Employees
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);//指定“Employee”对应表名及架构
modelBuilder.Entity&Employee&().HasKey(emp =& emp.No);//定义主键为“No”
//modelBuilder.Entity&Employee&().HasKey(emp =& new { emp.No, emp.Title });//指定&No&和“Title”作为复合主键,使用Data Annotations无法做到
modelBuilder.Entity&Employee&().Property(emp =& emp.No).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);//去掉标识列,前面我们也提到过通过Data Annotations通用可以去掉主键默认标示属性
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).HasMaxLength(30);//指定“Title”最大长度为30
modelBuilder.Entity&Employee&().Property(emp =& emp.BirthDate).IsRequired();//指定“BirthDate”为不可为空
modelBuilder.Entity&Employee&().Property(emp =& emp.Note).HasColumnName(&Notes&).HasColumnType(&ntext&);//指定“Note”对应列名为“Notes”,并指定数据类型
modelBuilder.Entity&Employee&().Ignore(emp =& emp.PhotoPath);//指定“PhotoPath”为非映射列
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).IsUnicode(true);//“Title”列是否支持Unicode编码
plexType&Name&().Property(n=&n.FirstName).HasMaxLength(50);//指定Name为复杂数据类型,并指定复杂类型中“FirstName”长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Name.LastName).HasMaxLength(20);//还可以通过这种方式指定复杂类型“Name”的“LastName”列的长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Address).IsConcurrencyToken();//指定“Address”进行并发控制,通常这一列我们知道为“TimeStamp”列而不是“Addree”这里只是为了说明可以标记其他列
modelBuilder.Entity&Employee&().Property(emp =& emp.TimeStamp).IsRowVersion();//通过指定“TimeStamp”进行并发版本控制
从上面的代码中可以看到基本上在Data Annotations中实现的功能使用Fluent API都实现了,并且在上面的代码注释中我也提到了一些Data Annotations无法实现的功能,具体代码基本上都已经注释了在此也不再解释了。
Fluent API关系配置
下面让看一下EF中关系配置的实现,看一下Fluent API如何进行实体关系约束,这里假设每个公司员工“Employee”在企业内部都有一个通讯账户“MessagingAcount”,这二者之间是一对一的关系;同时添加一个产品类“Product”,它与“Order”的关系是多对多的关系,具体定义如下:
MessageAcount类:
using System.Collections.G
using ponentModel.DataA
using System.L
using System.T
namespace CodeFirst.Entities
public class MessagingAccount
public int EmployeeNo
public Employee Employee
public string UserName
public string Password
Product类:
using System.Collections.G
using System.L
using System.T
namespace CodeFirst.Entities
public class Product
public int ProductID
public string ProductName
public double UnitPrice
public int OrderID
public List&Order& Orders
Employee类(添加了对应的属性):
using System.Collections.G
using ponentModel.DataA
using ponentModel.DataAnnotations.S
using System.L
using System.T
namespace CodeFirst.Entities
public class Employee
public int No
public Name Name
public string Title
public DateTime BirthDate
public string Address
public string Note
public DateTime CreateDate
public string PhotoPath
public byte[] TimeStamp
public List&Order& DeliverOrder
public List&Order& CheckOrder
public MessagingAccount Acount
Order类(添加了对应的属性):
using System.Collections.G
using ponentModel.DataAnnotations.S
using System.L
using System.T
namespace CodeFirst.Entities
public class Order
public int OrderID
public string OrderTitle
public string CustomerName
public DateTime TransactionDate
public int CustomerNo
public Customer Customer
public int ProductID
public List&Product& Products
public Employee DeliverPerson
public Employee CheckPerson
OrderContext类,定义了数据类之间的关系,主要是关系配置部分:
using System.Collections.G
using System.L
using System.T
using System.Data.E
using CodeFirst.E
using ponentModel.DataAnnotations.S
using System.Data.Entity.ModelConfiguration.C
namespace CodeFirst
public class OrderContext:DbContext
public OrderContext()
: base(&CodeFirstDb&)
Database.SetInitializer&OrderContext&(
new DropCreateDatabaseIfModelChanges&OrderContext&()
public DbSet&Order& Orders
public DbSet&Employee& Employees
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);//指定“Employee”对应表名及架构
modelBuilder.Entity&Employee&().HasKey(emp =& emp.No);//定义主键为“No”
//modelBuilder.Entity&Employee&().HasKey(emp =& new { emp.No, emp.Title });//指定&No&和“Title”作为复合主键,使用Data Annotations无法做到
modelBuilder.Entity&Employee&().Property(emp =& emp.No).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);//去掉标识列,前面我们也提到过通过Data Annotations通用可以去掉主键默认标示属性
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).HasMaxLength(30);//指定“Title”最大长度为30
modelBuilder.Entity&Employee&().Property(emp =& emp.BirthDate).IsRequired();//指定“BirthDate”为不可为空
modelBuilder.Entity&Employee&().Property(emp =& emp.Note).HasColumnName(&Notes&).HasColumnType(&ntext&);//指定“Note”对应列名为“Notes”,并指定数据类型
modelBuilder.Entity&Employee&().Ignore(emp =& emp.PhotoPath);//指定“PhotoPath”为非映射列
//modelBuilder.Entity&Customer&().HasRequired(c=&c.Orders).WithMany().Map(m=&m.MapKey(&CustomerOrder&));
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).IsUnicode(true);//“Title”列是否支持Unicode编码
plexType&Name&().Property(n=&n.FirstName).HasMaxLength(50);//指定Name为复杂数据类型,并指定复杂类型中“FirstName”长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Name.LastName).HasMaxLength(20);//还可以通过这种方式指定复杂类型“Name”的“LastName”列的长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Address).IsConcurrencyToken();//指定“Address”进行并发控制,通常这一列我们知道为“TimeStamp”列而不是“Addree”这里只是为了说明可以标记其他列
modelBuilder.Entity&Employee&().Property(emp =& emp.TimeStamp).IsRowVersion();//通过指定“TimeStamp”进行并发版本控制
/*下面代码演示EF中的关系约束*/
//modelBuilder.Entity&MessagingAccount&().HasRequired(a =& a.Employee).WithOptional(emp =& emp.Acount);//配置一对零关系,允许存在一个Employee而不存在MessagingAcount的情况(注意在Employee中添加Acont属性)
modelBuilder.Entity&Employee&().HasRequired(emp =& emp.Acount).WithRequiredPrincipal(a =& a.Employee);//配置一对一关系,和上面的WithOptionnal关系区别是每个Employee必须有一个MessagingAcount而每个MessageAcount也必须有一个Employee;但是Employee是主表,此时允许Employee单独持久化而不允许MessagingAcount单独持久化
//注意配置一对一关系也可以使用WithRequiredDependent,只不过主表发生了变化,上面的语句与下面的语句是等价的
//modelBuilder.Entity&MessagingAccount&().HasRequired(a =& a.Employee).WithRequiredDependent(a =& a.Acount);//
//下面的方法解决了一对一的关系,此时Employee和MessageAcount将必须同时存在
//modelBuilder.Entity&Employee&().HasRequired(emp =& emp.Acount).WithMany().HasForeignKey(emp =& emp.MessagingAccountID);
//modelBuilder.Entity&MessagingAccount&().HasRequired(a =& a.Employee).WithMany().HasForeignKey(a =& a.EmployeeNo);
//modelBuilder.Entity&Order&().HasRequired(o=&o.Customer).WithMany();//一对多的关系,一个Customer有多个Order(注意,运行之前先把Order中CustomerNo和Customer中的Orders属性删除掉,否则将生成两个外键一个是自动生成的另一个是Fluent API配置生成的,对应这种关系推荐使用默认生成)
//modelBuilder.Entity&Order&().HasRequired(o =& o.Customer).WithMany().WillCascadeOnDelete();//添加添加级联删除
//modelBuilder.Entity&Order&().HasRequired(o =& o.Customer).WithMany().Map(m=&m.MapKey(&Customer_Order&);//外键重命名
//modelBuilder.Entity&Order&().HasRequired(o =& o.Customer).WithMany().HasForeignKey(o =& new { o.CustomerNo,o.CustomerName});//组合外键,注意本例中没有组合外键(CustomerName不是外键),这里只是举例而已
//modelBuilder.Entity&Order&().HasRequired(o =& o.Customer).WithMany(c=&c.Orders).HasForeignKey(o =& o.CustomerNo);//指定外键(一般用户外键名不符合默认约束命名时)
modelBuilder.Entity&Order&().HasMany(o =& o.Products).WithMany(p =& p.Orders).Map(m =& {
m.ToTable(&OrderDetails&);
m.MapLeftKey(&OrderID&);
m.MapRightKey(&ProductID&);
});//配置多对多的关系,并指定了表名、对应的外键;注意如果不使用FluentAPI配置,Product和Order配置了相应的导航属性,EF也会默认生成一张表(表名为“&数据类1&+&数据类2&”)
运行生成的数据库结构如下图:
在上面的代码中我们着重看关系配置部分,我们注释了一部分关系约束配置代码主要是因为有些关系不能共存大家可以自己去掉执行试试,这部分代码希望初学者不要略过。关于上面的代码相信大家看注释都可以明白,这里我主要强调一点,那就是多重外键约束。大家通过上图已经看到CheckPerson和DeliverPerson的约束像在Data Annotations中提到的一样并没有达到我们的预期,其主要原因是因为EF并没有明白这种约束关系,解决办法很简单,只要配置“Employee”和“Order”一对多约束关系即可(注意只有配置一个属性即可,例如我们配置CheckPerson):
modelBuilder.Entity&Order&().HasRequired(o =& o.CheckPerson).WithMany(emp =& emp.CheckOrder).WillCascadeOnDelete();
Fluent API继承实现
下面看一下EF强大的继承实现,在EF中支持三种类型的继承实现:
Table-Per-Hierarchy(TPH):EF默认支持的类型,无需配置即可实现,整个层次在一张表中,基类中没有的属性被标记为可空,通过添加一个额外的“Discniminator”列进行类型区分;
Table-Per-Type(TPT):每个类型一张表,在子类中包含自身属性和一个指向基类的外键列;
Table-Per-Concrete Calss(TPC):每个类型一张表,但是和TPT不同的是子类中并没有创建外键列而是直接将基类的属性在子类中展开(子类表包含基类表的所有列);
在演示上面几种方式之前先让我们定义两个类“Worker”表示当前在职员工和“Retired”表示退休员工,它们继承于“Employee”。
TPH方式是EF默认支持,我们无需更多的配置即可完成。
Worker类:
using System.Collections.G
using System.L
using System.T
namespace CodeFirst.Entities
public class Worker:Employee
public decimal AnnualSalary
Retired类:
using System.Collections.G
using System.L
using System.T
namespace CodeFirst.Entities
public class Retired:Employee
public decimal MonthlyPension
接下来插入两条数据进行测试:
using System.Collections.G
using System.Data.E
using System.Data.SqlC
using System.L
using System.T
using CodeF
using CodeFirst.E
namespace CodeFirst
class Program
static void Main(string[] args)
using (var db = new OrderContext())
db.Workers.Add(new Worker()
Name = new Name { FirstName=&Stephen&,LastName=&Chow&},
Title = &Software Architect&,
BirthDate=new DateTime(),
Address=&Peking&,
CreateDate=DateTime.Now,
AnnualSalary=
db.Retireds.Add(new Retired
Name = new Name { FirstName = &Jeffrey&, LastName = &Lee& },
Title = &Software Development Engineer&,
BirthDate = new DateTime(),
Address = &Hong Kong&,
Note = &&,
CreateDate = DateTime.Now,
MonthlyPension=9999999
db.SaveChanges();
下面是具体结果:
使用TPT方式其实也十分简单,只需要配置基类及子类生成的表信息即可:
using System.Collections.G
using System.L
using System.T
using System.Data.E
using CodeFirst.E
using ponentModel.DataAnnotations.S
using System.Data.Entity.ModelConfiguration.C
namespace CodeFirst
public class OrderContext:DbContext
public OrderContext()
: base(&CodeFirstDb&)
Database.SetInitializer&OrderContext&(
new DropCreateDatabaseIfModelChanges&OrderContext&()
public DbSet&Order& Orders
public DbSet&Employee& Employees
public DbSet&Worker& Workers
public DbSet&Retired& Retireds
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);//指定“Employee”对应表名及架构
modelBuilder.Entity&Employee&().HasKey(emp =& emp.No);//定义主键为“No”
//modelBuilder.Entity&Employee&().HasKey(emp =& new { emp.No, emp.Title });//指定&No&和“Title”作为复合主键,使用Data Annotations无法做到
modelBuilder.Entity&Employee&().Property(emp =& emp.No).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);//去掉标识列,前面我们也提到过通过Data Annotations通用可以去掉主键默认标示属性
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).HasMaxLength(30);//指定“Title”最大长度为30
modelBuilder.Entity&Employee&().Property(emp =& emp.BirthDate).IsRequired();//指定“BirthDate”为不可为空
modelBuilder.Entity&Employee&().Property(emp =& emp.Note).HasColumnName(&Notes&).HasColumnType(&ntext&);//指定“Note”对应列名为“Notes”,并指定数据类型
modelBuilder.Entity&Employee&().Ignore(emp =& emp.PhotoPath);//指定“PhotoPath”为非映射列
//modelBuilder.Entity&Customer&().HasRequired(c=&c.Orders).WithMany().Map(m=&m.MapKey(&CustomerOrder&));
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).IsUnicode(true);//“Title”列是否支持Unicode编码
plexType&Name&().Property(n=&n.FirstName).HasMaxLength(50);//指定Name为复杂数据类型,并指定复杂类型中“FirstName”长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Name.LastName).HasMaxLength(20);//还可以通过这种方式指定复杂类型“Name”的“LastName”列的长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Address).IsConcurrencyToken();//指定“Address”进行并发控制,通常这一列我们知道为“TimeStamp”列而不是“Addree”这里只是为了说明可以标记其他列
modelBuilder.Entity&Employee&().Property(emp =& emp.TimeStamp).IsRowVersion();//通过指定“TimeStamp”进行并发版本控制
/*下面代码演示EF中的继承关系实现*/
//TPH默认支持,无需手动进行配置
//TPT,只需要指定生成的表即可
modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);
modelBuilder.Entity&Worker&().ToTable(&Worker&, &Person&);
modelBuilder.Entity&Retired&().ToTable(&Retired&, &Person&);
生成的表结构如下:
最后看一下TPC方式,TPC方式同TPT一样同样是每个类型创建一张表,不同的是TPC每个子类中只有子类特有属性和外键列,子类通过外键查找基类属性;而在TPC方式中每个子类和基类之间并没有创建约束关系,子类表中拥有自身属性和基类所有属性。TPC定义方式也很简单,只需要在子类中通过“MapInheritedProperties”方法指定集成基类属性即可:
using System.Collections.G
using System.L
using System.T
using System.Data.E
using CodeFirst.E
using ponentModel.DataAnnotations.S
using System.Data.Entity.ModelConfiguration.C
namespace CodeFirst
public class OrderContext:DbContext
public OrderContext()
: base(&CodeFirstDb&)
Database.SetInitializer&OrderContext&(
new DropCreateDatabaseIfModelChanges&OrderContext&()
public DbSet&Order& Orders
public DbSet&Employee& Employees
public DbSet&Worker& Workers
public DbSet&Retired& Retireds
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);//指定“Employee”对应表名及架构
modelBuilder.Entity&Employee&().HasKey(emp =& emp.No);//定义主键为“No”
//modelBuilder.Entity&Employee&().HasKey(emp =& new { emp.No, emp.Title });//指定&No&和“Title”作为复合主键,使用Data Annotations无法做到
modelBuilder.Entity&Employee&().Property(emp =& emp.No).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);//去掉标识列,前面我们也提到过通过Data Annotations通用可以去掉主键默认标示属性
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).HasMaxLength(30);//指定“Title”最大长度为30
modelBuilder.Entity&Employee&().Property(emp =& emp.BirthDate).IsRequired();//指定“BirthDate”为不可为空
modelBuilder.Entity&Employee&().Property(emp =& emp.Note).HasColumnName(&Notes&).HasColumnType(&ntext&);//指定“Note”对应列名为“Notes”,并指定数据类型
modelBuilder.Entity&Employee&().Ignore(emp =& emp.PhotoPath);//指定“PhotoPath”为非映射列
//modelBuilder.Entity&Customer&().HasRequired(c=&c.Orders).WithMany().Map(m=&m.MapKey(&CustomerOrder&));
modelBuilder.Entity&Employee&().Property(emp =& emp.Title).IsUnicode(true);//“Title”列是否支持Unicode编码
plexType&Name&().Property(n=&n.FirstName).HasMaxLength(50);//指定Name为复杂数据类型,并指定复杂类型中“FirstName”长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Name.LastName).HasMaxLength(20);//还可以通过这种方式指定复杂类型“Name”的“LastName”列的长度
//modelBuilder.Entity&Employee&().Property(emp =& emp.Address).IsConcurrencyToken();//指定“Address”进行并发控制,通常这一列我们知道为“TimeStamp”列而不是“Addree”这里只是为了说明可以标记其他列
modelBuilder.Entity&Employee&().Property(emp =& emp.TimeStamp).IsRowVersion();//通过指定“TimeStamp”进行并发版本控制
/*下面代码演示EF中的继承关系实现*/
//TPH默认支持,无需手动进行配置
//TPT,只需要指定生成的表即可
//modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);
//modelBuilder.Entity&Worker&().ToTable(&Worker&, &Person&);
//modelBuilder.Entity&Retired&().ToTable(&Retired&, &Person&);
//TPC,只要子类中指定映射继承属性即可
modelBuilder.Entity&Employee&().ToTable(&People&, &Person&);
modelBuilder.Entity&Worker&().Map(m =& {
m.MapInheritedProperties();
m.ToTable(&Worker&, &Person&);
modelBuilder.Entity&Retired&().Map(m =&
m.MapInheritedProperties();
m.ToTable(&Retired&, &Person&);
生成的表结构如下:
注意:尽管Fluent API功能更加强大,对于可以使用Data Annotations实现的功能我们推荐使用Data Annotations方式。
至此关于EF中默认约定及自定义配置的内容已经讨论结束了,关于EF中如何进行查询以及如何优化查询等更多内容敬请关注后面的文章。

我要回帖

更多关于 using system.io 的文章

 

随机推荐