8,继承与关系
概要:
对于一张表,可能存在多重类型。我们可以用继承来定义它们。
实体关系的应用,解决数据表和表之间一些复杂问题。
内容:
论坛主题表 dbo.Topics:
字段名 |
字段类型 |
可空 |
备注 |
TopicID |
int |
not null |
identity/主键 |
TopicTitle |
varchar(50) |
not null |
|
TopicContent |
varchar(max) |
not null |
|
ParentTopic |
int |
null |
如果帖子是主题贴这个字段为null,否则就是所属主题id |
TopicType |
tinyint |
not null |
0 – 主题贴 1 – 回复帖 |
定义实体类父类:包含都存在的部分字段。
然后定义可能出现的子类。
再定义各个类和字段的特性。
用[InheritanceMapping(。。)]判断类型
用[Column(IsDiscriminator=true)]标示判断依据
//基类
[Table(Name="Topics")]
[InheritanceMapping(Code=0,Type=typeof(NewTopic),IsDefault=true)]
[InheritanceMapping(Code=1,Type=typeof(Reply))]
public class Topic
{
[Column(IsPrimaryKey=true,IsDbGenerated=true)]
public int TopicID { get; set; }
[Column]
public string TopicTitle { get; set; }
[Column]
public string TopicContent { get; set; }
[Column(IsDiscriminator=true)]
public int TopicType { get; set; }
}
//新帖,TopicType=0,且主题字段ParentTopic为null,即不存在
public class NewTopic : Topic
{
public NewTopic()
{
base.TopicType = 0;
}
}
//回复贴,帖子类型TopicType=1,且主题字段为主题帖ID
public class Reply : Topic
{
public Reply()
{
base.TopicType = 1;
}
[Column]
public int ParentTopic { get; set; }
}
定义完实体类,下面就是使用方法,首先定义DataContext:
//定义DataContext类
public partial class BBSContext : DataContext
{
public Table<Topic> Topics;
public BBSContext(string connection) : base(connection) { }
}
读出来Topic类,然后foreach逐行判断类型,然后再转换类型:
BBSContext ctx = newBBSContext("");
var query = from c in ctx.Topics select c;
foreach(Topic t in query )
{
if (t is NewTopic)
{
NewTopic newtopic = t asNewTopic;
//newtopic就是可以使用的NewTopic类型
}
else if(t is Reply)
{
Reply reply = t asReply;
//reply就是可以使用的Reply类型
}
}
或直接使用:
IEnumerable<NewTopic> tb = (from t inctx.Topics.OfType<NewTopic>() select t).ToList();
Replyrpl =ctx.Topics.OfType<Reply>().Single(reply=> reply.TopicID == 8);
实体关系的使用:
1、 论坛版块分类表 dbo.Categories:
字段名 |
字段类型 |
可空 |
备注 |
CategoryID |
int |
not null |
identity/主键 |
CategoryName |
varchar(50) |
not null |
|
2、 论坛版块表 dbo.Boards:
字段名 |
字段类型 |
可空 |
备注 |
BoardID |
int |
not null |
identity/主键 |
BoardName |
varchar(50) |
not null |
|
BoardCategory |
int |
not null |
对应论坛版块分类表的CategoryID |
实体类:
[Table]
public class Categories
{
public Categories()
{
this._Boards = newEntitySet<Boards>();
}
private EntitySet<Boards>_Boards;
[Association(ThisKey="Category",Storage="_Boards")]
public EntitySet<Boards> Boards
{
get { return this._Boards; }
set { this._Boards.Assign(value); }
}
[Column(IsPrimaryKey=true,IsDbGenerated=true)]
public int CategoryID { get; set; }
[Column]
public string CategoryName { get; set; }
}
[Table]
public class Boards
{
[Association(ThisKey="Category",Storage="_Category")]
public Categories Category
{
get { return this._Category.Entity;}
set
{
this._Category.Entity = value;
value.Boards.Add(this );
}
}
private EntityRef<Categories>_Category;
[Column(IsPrimaryKey=true,IsDbGenerated=true)]
public int BoardID { get; set; }
[Column]
public string BoardName { get; set; }
[Column]
public int BoardCategory { get; set; }
}
使用:
Response.Write("-------------查询分类为1的版块-------------<br/>");
var query1 = fromb in ctx.Boards whereb.Category.CategoryID == 1 select b;
foreach (Boardb in query1)
Response.Write(b.BoardID + " " + b.BoardName + "<br/>");
Response.Write("-------------查询版块大于2个的分类-------------<br/>");
var query2 = fromc in ctx.BoardCategories where c.Boards.Count > 2 selectc;
foreach (BoardCategoryc in query2)
Response.Write(c.CategoryID + " " + c.CategoryName + " " +c.Boards.Count + "<br/>");
使用:
DataLoadOptionsoptions = new DataLoadOptions();
options.LoadWith<BoardCategory>(c => c.Boards);
ctx.LoadOptions = options;
Response.Write("-------------查询版块大于2个的分类-------------<br/>");
varquery2 = from c inctx.BoardCategories where c.Boards.Count > 2select c;
foreach(BoardCategory c inquery2)
Response.Write(c.CategoryID + " " + c.CategoryName + " " +c.Boards.Count + "<br/>");
使用:
BoardCategory dbcat= new BoardCategory(){ CategoryName = "Database" };
Boardoracle = new Board(){ BoardName = "Oracle", Category =dbcat};
ctx.BoardCategories.Add(dbcat);
ctx.SubmitChanges();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述