当前位置: 代码网 > it编程>编程语言>Asp.net > Entity Framework使用DBContext实现增删改查

Entity Framework使用DBContext实现增删改查

2024年05月18日 Asp.net 我要评论
有一段时间没有更新博客了,赶上今天外面下雨,而且没人约球,打算把最近对entity framework dbcontext使用的心得梳理一下,早些时候在网上简单查过,对于最新版本的ef并没有类似的知识

有一段时间没有更新博客了,赶上今天外面下雨,而且没人约球,打算把最近对entity framework dbcontext使用的心得梳理一下,早些时候在网上简单查过,对于最新版本的ef并没有类似的知识梳理类文章,希望对大家有所帮助。

1. 不要code first, 也不要db first

我为什么讨厌code first和db first呢?首先code first是先写代码,数据库完全由代码生成,开发阶段尚可,一旦到了产品发布阶段,如果需要添加字段,我们总不能用 visual studio去生产环境上去更新数据库吧,听起来就很可怕。而且另外的一个问题自动是生成的数据库脚本也不可控,还不如自己提前设计好。db first也好不了哪去,反向转过来的代码包含很多没有用的文件,而且数据库的更新还要重新走model生成过程,简直无法理解为什么会有这样的设计。说了这么多,怎么解决呢?

数据库和领域模型分开设计,按照对应关系映射字段,使用自定义链接字串,既不使用领域模型生成数据库,也不用数据库生成领域模型,示例代码如下,sql code 以 destinations和ttable表为例:

create table [dbo].[destinations]
(
    [destinationid] [int] primary key not null,
    [name] [nvarchar](max) null,
    [country] [nvarchar](max) null,
    [description] [nvarchar](max) null,
    [photo] [varbinary](max) null
create table [ttt].[ttable]

(

 [id] [int] primary key not null,

 [name] [nvarchar](max) null

)

model class:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;

namespace model
{
    public class destination
    {
        public int destinationid { get; set; }
        public string name { get; set; }
        public string country { get; set; }
        public string description { get; set; }
        public byte[] photo { get; set; }
        public list<lodging> lodgings { get; set; }
    }

    public class lodging
    {
        public int lodgingid { get; set; }
        public string name { get; set; }
        public string owner { get; set; }
        public bool isresort { get; set; }
        public destination destination { get; set; }
    }

    public class ttable
    {
        public int id { get; set; }
        public string name { get; set; }
    }
}

connect string:

<connectionstrings>
    <add name="bacontext" connectionstring="data source=(localdb)\mssqllocaldb;initial catalog=dataaccess.breakawaycontext;integrated security=sspi;" providername="system.data.sqlclient" />
  </connectionstrings>

db context:

using system.data.entity;
using system.data.entity.modelconfiguration;
using model;

namespace dataaccess
{
    public class ttableconfiguration : entitytypeconfiguration<ttable>
    {
        public ttableconfiguration()
        {
            this.totable("ttable", "ttt");
        }
    }

    public class breakawaycontext : dbcontext
    {

        protected override void onmodelcreating(dbmodelbuilder modelbuilder)
        {
            modelbuilder.configurations.add(new ttableconfiguration());
        }

        public breakawaycontext(string connstring) : base(connstring)
        {
        }
        public dbset<destination> destinations { get; set; }
        public dbset<lodging> lodgings { get; set; }
        public dbset<ttable> ttables { get; set; }
    }
}

2. 如果数据库的表的字段和领域模型的字段不对应,如何处理呢?比如本文的ttable表是在ttt  schema下面的, 而其他表示设计在dbo下面,最方便的方式是使用fluent api, 具体代码如请参见 ttableconfiguration class和 onmodelcreating()方法,可配置的粒度非常细,比如可以配置领域模型和数据库的哪个schema的哪张表的哪一列对应,本文是将ttable 类的数据库表配置为了ttt  schema下的ttable表,

    public class ttableconfiguration : entitytypeconfiguration<ttable>
    {
        public ttableconfiguration()
        {
            this.totable("ttable", "ttt");
        }
    }

3. 增删该查自带事物支持,具体代码如下,

        public static int insert()
        {
            var destination = new destination
            {
                country = "chs",
                description = "chs is the language package",
                name = "xsss"
            };
            using (var context = new breakawaycontext(configurationmanager.connectionstrings["bacontext"].connectionstring))
            {
                var rt = context.destinations.add(destination);
                context.savechanges();
                return rt.destinationid;
            }
        }

        public static void update(destination destin)
        {
            using (var context = new breakawaycontext(configurationmanager.connectionstrings["bacontext"].connectionstring))
            {
                var dest = context.destinations.where(a => a.destinationid == destin.destinationid).single();
                dest.name = destin.name;
                context.savechanges();
            }
        }

        public static void delete(int destid)
        {
            using (var context = new breakawaycontext(configurationmanager.connectionstrings["bacontext"].connectionstring))
            {
                var destination = new destination() { destinationid = destid };
                context.destinations.attach(destination);
                context.destinations.remove(destination);

                context.savechanges();
            }
        }


        public static destination query(int destid)
        {
            using (var context = new breakawaycontext(configurationmanager.connectionstrings["bacontext"].connectionstring))
            {
                iqueryable<destination> dest = context.destinations.where(a => a.destinationid == destid);

                return dest.single();
            }
        }

4. 如果需要多个操作同时成功或者失败,需要手动开启事务,具体代码如下,

        public static void transactionops()
        {
            using (var context = new breakawaycontext(configurationmanager.connectionstrings["bacontext"].connectionstring))
            {
                using (var dbcontexttransaction = context.database.begintransaction())
                {
                    try
                    {
                        var destination = new destination
                        {
                            country = "chs",
                            description = "chs is the language package",
                            name = "xs2s"
                        };

                        var destid = context.destinations.add(destination);

                        context.savechanges();

                        context.destinations.attach(destid);
                        context.destinations.remove(destid);

                        context.savechanges();

                        dbcontexttransaction.commit();
                    }
                    catch (system.exception ex)
                    {
                        dbcontexttransaction.rollback();
                        system.console.writeline(ex.tostring());
                    }
                }
            }
        }

5. 分页查询是网站设计的常用功能,一个简单的真分页查询方法如下如下所示,

        public static list<destination> querypaging<tkey>(int pageindex, int pagesize, expression<func<destination, bool>> wherelambda, expression<func<destination, tkey>> orderby)
        {
            using (var context = new breakawaycontext(configurationmanager.connectionstrings["bacontext"].connectionstring))
            {
                return context.destinations.where(wherelambda).orderby(orderby).skip((pageindex - 1) * pagesize).take(pagesize).tolist();
            }
        }

总结

本文对最新版本的entity framework进行增删改查操作给出了详尽的解释,并且给出了数据库和领域模型代码分开设计的完整解决方案,同时介绍了手动数据库表和领域模型映射,数据库事务实现,分页查询等常用功能,希望对大家有所帮助。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对代码网的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com