惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
S
Schneier on Security
T
Threat Research - Cisco Blogs
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Hacker News
The Hacker News
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
T
Tenable Blog
S
Secure Thoughts
T
Threatpost
V2EX - 技术
V2EX - 技术
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
小众软件
小众软件
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Y
Y Combinator Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
P
Privacy International News Feed
H
Heimdal Security Blog
量子位
B
Blog

博客园 - 海南K.K

海南海口滨海大道洛杉矶城一线海景公寓出售(09年建成,面积88~126平米共六套,一次性团购可打折) 出售海南海口南渡江畔私家别墅(楼高4层,占地388平米,建筑面积570平米) 代友发布:海南海口海景豪宅转让(16层5室3厅3卫2阳台288.0m²) 百度谈人生?别再往自己脸上贴金了! douban api,你到底想做什么? Javascript: 从最受误解的语言,到最流行的语言 LINQ那些事(9)-解析Table<T>.Attach引发的异常和解决方法 你可能不熟悉的CSS 三言二拍:海南的软件业 海口房事:海口纵贯线(-海南购房-海口购房-海南二手房-海口二手房-海南国际旅游岛-养老-过冬-) 海口房事:看京城人争当海南岛民 (-海南购房-海口购房-海南二手房-海口二手房-过冬-养老-国际旅游岛-) 海南海口生态公园公寓出售-海南购房-海口购房-海南二手房-海口二手房-过冬-养老-国际旅游岛- Code4Fun: 通过XML模板系统实现对象的灵活序列化 LINQ那些事儿(5)- 动态查询 LINQ那些事儿(4)- Query Expression和Query Operator LINQ那些事儿(3)- 事务和并发冲突处理 LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作 LINQ那些事 LINQ那些事儿(6)-对象生命周期管理
LINQ那些事儿(1)- 定义从关系数据库到entity class的映射
海南K.K · 2009-12-31 · via 博客园 - 海南K.K

和多数O/R框架一样, LINQ2SQL可以通过Attribute标签定义和XML映射文件,两种方式来实现关系数据到实体类的映射。在MSDN上有关于这两种方法的详细介绍,本文只是作为快速向导。

在LINQ2SQL中,所有的数据操作的入口都是DataContext对象,如下面的代码示例了访问Northwnd数据库的Customer数据:

    class Program
    {
        static void Main(string[] args)
        {
            using(var context = CreateContext())
            {
                context.Log = Console.Out;
                var customers = context.GetTable<Customer>().Take(10);

                foreach (var item in customers)
                {
                    Console.WriteLine(item.CompanyName);
                }
            }
        }

        static DataContext CreateContext()
        { 
            var path = System.IO.Path.Combine(
                 AppDomain.CurrentDomain.BaseDirectory, "northwnd.xml");
            var connectionString = System.IO.Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, "northwnd.mdf");
            var mapping = XmlMappingSource.FromXml(System.IO.File.ReadAllText(path));
            var context = new DataContext(connectionString, mapping);

            return context;
        }
    }

更完整的通过DataContext实现SqlServer数据库的CRUD操作的方法,请参考LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作。CreateContext()函数通过传递数据库mdf文件的路径和映射信息,构造了一个DataContext对象,通过DataContext对象,我们可以对该数据库进行任何的操作,包括CRUD,甚至是删除或创建一个新的数据库文件。为了便于示例,本文用了Sqlexpress的本地数据库文件,你可以修改connectionString指向正式SqlSever上的数据库。

关于DataContext的详细说明,请参考MSDN:http://msdn.microsoft.com/zh-cn/library/system.data.linq.datacontext.aspx

我们来关注传递给DataContext构造函数的第二个参数——mapping,mapping对象中包含了Northwnd数据库和实体类之间的映射关系。LINQ2SQL通过System.Data.Linq.Mapping.MappingSource来作为映射关系的基类,并且在.Net Framework 3.5中提供了AttributeMappingSource和XmlMappingSource,分别表示了两种定义映射关系的方法——通过在实体类上用Attribute标签来定义,以及通过外部Xml文件来定义映射关系。

当使用一些开源的ORM框架时,你可能不得不手写定义这些映射信息,或者通过第三方的工具来实现映射信息的生成。对于LINQ2SQL,同样可以用手写定义,但是微软已经为我们提供了足够好的生成工具——O/R Designer和SqlMetal。

参考资料:

基于属性的映射http://msdn.microsoft.com/zh-cn/library/bb386971.aspx

使用O/R Designer生成对象模型 http://msdn.microsoft.com/zh-cn/library/bb384429.aspx

使用SqlMetal.exe生成对象模型http://msdn.microsoft.com/zh-cn/library/bb386987.aspx

通过O/R Desginer或SqlMetal,你不但可以生成实体类的定义,而且还生成了一个DataContext的派生类,名称为xxxDataContext(xxx为默认数据库的名称,也可以自行定义)。在文章开始的代码中,我们通过DataContext.GetTable<Customer>()来获取操作Customer表的表对象,但在xxxDataContext类中提供了更方便的方法,通过访问xxxDataContext类中包含的Customers属性即可。

需要注意的是,在SqlServer中你允许设计一张没有主键标识(Primary key)的数据表,但是在定义entity class的属性时,必须至少包含一个的主键属性(IsPrimaryKey=true)。这不单是数据库设计标准的要求,DataContext对象会使用PrimaryKey属性值作为实体对象的唯一标识,用来进行实体对象的生命周期管理,详见LINQ那些事(6)。

我不建议你使用手写的方法来定义entity class,甚至是必须用O/R Designer或Sqlmetal来生成entity class,因为对于包含关联关系(Association)的entity class,自动生成的代码中还包含了维护Association的代码,这对LINQ2SQL实现级联操作是非常关键的(你可以看看生成的Customer类的代码,它如何维护Orders属性)。

还有一个问题是通过Attribute标签和Xml映射文件来定义映射关系,孰优孰劣的问题,这已经是一个老问题了。听到最多的是,有人说大项目用XML方式,小项目用Attribute方式,我觉得那纯粹是瞎扯淡,但XML方式的确有一个好处就是有时当数据库发生更改时,我们直接修改XML就可以了,而无需重新编译代码,其他的更多就是习惯问题了。在这一系列的文章中,我都采用了XML的方式来定义,文章开始的代码示例了如何由XML来创建DataContext对象,你只需把DataContext改成xxxDataContext即可。

顺便提供几个非常常用的sqlmetal参数组合:(拷贝时注意去掉northwnd.和cs之间的断行)

  • 1、生成本地数据库文件的映射:sqlmetal "northwnd.mdf" /code:northwnd.
    cs /map:northwnd.xml /namespace:LinqAttach /context:Northwnd /pluralize
  • 2、通过链接字符串:sqlmetal /conn:”server=myserver; database=northwind” /code:northwnd.
    cs /map:northwnd.xml /namespace:LinqAttach /context:Northwnd /pluralize
  • 3、通过指定数据源:sqlmetal /server:myserver /database:northwnd /password:pwd /code:northwnd.
    cs /map:northwnd.xml /namespace:LinqAttach /context:Northwnd /pluralize

说明:

/code:指定包含生成实体类和派生DataContext类的cs代码的文件路径

/map:指定生成xml映射文件路径

/namespace:指定生成的cs代码所在的命名空间

/context:指定生成的派生DataContext类的类名

/pluralize:指定sqlmetal根据英文单/复数规则来生成实体类和属性的名称,非常靠谱。

链接

LINQ那些事(总)

1、 LINQ那些事儿(1)- 定义从关系数据库到Entity Class的映射

2、 LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作

3、 LINQ那些事儿(3)- 事务和并发冲突处理

4、 LINQ那些事儿(4)- Query Expression和Query Operator

5、 LINQ那些事儿(5)- 动态查询

6、 LINQ那些事儿(6)- DataContext的对象生命周期管理

7、 LINQ那些事儿(7)- 通过自定义IEnumerable<T>来扩展LINQ

8、LINQ那些事儿(8)- 通过自定义IQueryable<T>和IQueryableProvider来扩展LINQ