您的位置:首页 > 移动开发

ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

2018-04-22 01:54 2883 查看

ADO.NET

 

一、ADO.NET概要

ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库

二、ADO.NET的组成

①System.Data  → DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint,DataColumnMapping,DataTableMapping

②System.Data.Coummon     → 各种数据访问类的基类和接口

③System.Data.SqlClient   → 对Sql Server进行操作的数据访问类

主要有:   a) SqlConnection            → 数据库连接器
            b) SqlCommand               → 数据库命名对象
            c) SqlCommandBuilder        → 生存SQL命令
            d) SqlDataReader            → 数据读取器
            e) SqlDataAdapter           → 数据适配器,填充DataSet
            f) SqlParameter             → 为存储过程定义参数
            g) SqlTransaction           → 数据库事物

三、Connection连接对象

Connection对象也称为数据库连接对象,Connection对象的功能是负责对数据源的连接。所有Connection对象的基类都是DbConnection类。 

3.1、连接字符串

基本语法:数据源(Data Source)+数据库名称(Initial Catalog)+用户名(User ID)+密码(Password)

3.1.1、SQL Server连接字符串

Data Source=.;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;

3.1.2、Access连接字符串

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\myDatabase.mdb;User Id=admin;Password=;

3.1.3、MySQL连接字符串

Server=myServerAddress;Database=myDatabase;Uid=myUsername;Pwd=myPassword;

3.1.4、DB2连接字符串

Server=myAddress:myPortNumber;Database=myDatabase;UID=myUsername;PWD=myPassword;

3.1.5、Oracle连接字符串

Data Source=TORCL;User Id=myUsername;Password=myPassword; 

在VS中获得连接字符串并连接到数据库:工具->连接到数据库

3.2、连接到数据库

Connection对象有两个重要属性: 

(1)ConnectionString:表示用于打开 SQL Server 数据库的字符串; 
(2)State:表示 Connection 的状态,有Closed和Open两种状态。 

Connection对象有两个重要方法:

(1)Open()方法:指示打开数据库;

(2)Close()方法:指示关闭数据库。

四、Command对象

Command对象也称为数据库命令对象,Command对象主要执行包括添加、删除、修改及查询数据的操作的命令。也可以用来执行存储过程。用于执行存储过程时需要将Command对象的CommandType 属性设置为CommandType.StoredProcedure,默认情况下CommandType 属性为CommandType.Text,表示执行的是普通SQL语句。

Command主要有三个方法:

4.1、ExecuteNonQuery

ExecuteNonQuery()执行一个非查询SQL语句,返回受影响的行数,这个方法主要用于执行对数据库执行增加、更新、删除操作,注意查询的时候不是调用这个方法。用于完成insert,delete,update操作。执行时返回影响行数。

using 关键字有两个主要用途:
  (
).作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型。
  (
).作为语句,用于定义一个范围,在此范围的末尾将释放对象。

using只能用于实现了IDisposable接口的类型,禁止为不支持IDisposable接口的类型使用using语句,否则会出现编译错误;

4.1.1、拼接字符串
string str = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", txtSQLAdd.Text, txtSqlName.Text, txtUser.Text, txtPwd.Text);

4.1.2、参数

如果直接拼接字符串会存在安全隐患,使用参数可以解决问题。

4.1.3、增加、删除、修改

这里的示例是insert,如果想执行delete与update代码是一样的,只是变化了SQL。

增加:insert [into] <表名> (列名) values (列值)     例:insert into Strdents (姓名,性别,出生日期) values ('开心朋朋','男','1980/6/15')

删除:delete from <表名> [where <删除条件>]    例:delete from a where name='开心朋朋'(删除表a中列值为开心朋朋的行)

修改:update <表名> set <列名=更新值> [where <更新条件>]    例:update tongxunlu set 年龄=18 where 姓名='蓝色小名'

4.2ExecuteScalar ()

ExecuteScalar ()从数据库检索单个值。这个方法主要用于统计操作。ExecuteScalar ()这个方法是针对SQL语句执行的结果是一行一列的结果集,这个方法只返回查询结果集的第一行第一列。针对SQL聚合函数(count,max,min,avg,sum)使用。

聚合函数:select count(*) from <表名>

可能返回NULL值,需要对结果进行判断。

if (object.Equals(my,null))  //可以使用Equals进行Null值的判断,易读性强
  Console.WriteLine("Not Data");
else
  Console.WriteLine("Yes");

五、ExecuteReader获得数据

ExecuteReader用于实现只进只读的高效数据查询。用来读取一个数据表。用于查询一个数据表。

ExecuteReader:返回一个SqlDataReader对象,可以通过这个对象检查查询结果。它提供的是只进只读的执行方式,读取一行之后,移动到下一行,上一行的数据就不能使用了。手动调用Read()方法之后,SqlDataReader对象才会移到结果集的第一行。Read()方法会返回一个bool值,True则下行可用,false表示下行不可用。

5.1、使用ExecuteReader实现数据查询

//执行查询返回结果集
                SqlDataReader sdr = cmd.ExecuteReader();
                //下移游标,读取一行,如果没有数据了则返回false
                while (sdr.Read())
                {
                    Console.WriteLine("编号:" + sdr["Id"] + ",车名:" + sdr["Title"] + ",速度:" + sdr["Speed"]);
                }

5.2、实体类

实体类用于封装及映射数据。

5.3DataGridView展示数据

 

定义一个表示对象的类

定义一个对象的列表

初始化一个对象,用sqlReader()将数据读出后存入对象。

把对象加入对象列表中。

对象列表与DataGridView 显示。

 

窗口间的传值

一个窗口定义一个对象【1】

在另外一个窗口定义一个对象2

显示窗口的时候把1赋值给2

在窗口2加载的时候把2的属性显示出来

 

 

 

.net core2.0添加json文件并转化成类注入控制器使用

  上一篇,我们介绍了如何读取自定义的json文件,数据是读取出来了,只是处理的时候太麻烦,需要一遍一遍写,很枯燥.那么有没有很好的办法呢?经过钻研,办法有了.

  既然一个一个读取比较麻烦,那么可以把它放入一个类里面么?当然可以.这样直接注入这个类,让控制器去读取,那么就不需要每次加载它了,一次加载就可以在任何地方使用了.

  由于本文是接这上一篇文章的更新介绍,请先读取上一篇文章再浏览此篇文章

(1):在Models文件夹中添加类Class,并填写如下代码:

(2):更新Startup.cs脚本,更新函数ConfigureServices:

(3):更新Home控制器,将配置类注入进来并使用:

(4):运行项目,查看运行结果,成功:

总结:如果将配置文件一个一个读取的话是可行的,只是太麻烦,如果其他地方也需要用到的话又需要再次加载读取,浪费开发效率与运行效率.直接以类的方式加载并注入,可以让它在每个地方运行,消耗最少,效率最高.

 

 

 

 

 

 

简单了解 iTextSharp实现HTML to PDF

查了下 转PDF的各种框架   发现大部分都是收费的。 发现一款免费的iTextSharp  就想玩一下

只是简单做个HTML 转PDF  没有过深的探究。 

 

首先 我在项目中引入iTextSharp   还是老方法 要么 NuGet上下载 或者 直接命令 

 

然后在项目中建了一个HTML   里面就是一些简单的标签 和一些占位符

 

然后建了个PDF帮助类  里面实现具体转换的方法

public class PDFHelp
{
public byte[] ConvertHtmlTextToPDF(string htmltext)
{
if (string.IsNullOrEmpty(htmltext))
{
return null;
}
//避免htmlText没有任何html tag标签的純文字时,转PDF时会挂掉,所以一律加上<p>标签
//htmlText = "<p>" + htmltext + "</p>";

MemoryStream stream = new MemoryStream();
byte[] data = Encoding.UTF8.GetBytes(htmltext);
MemoryStream msInput = new MemoryStream(data);
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, stream);
//指定文件默认缩放标准100%
PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
doc.Open();
//使用XMLWorkerHelper把Html parse到PDF
XMLWorkerHelper .GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8, new UnicodeFontFactory());
//將pdfDest 写入到PDF
PdfAction action = PdfAction.GotoLocalPage(1, pdfDest, writer);
writer.SetOpenAction(action);
doc.Close();
msInput.Close();
stream.Close();
//回传PDF
return stream.ToArray();
}
}

 

占位符的简单替换 测试下。只写了三个 举个例子

public string Placeholderfill(string htmlContext)
{
var entity = _shopingRepository.FindAll().FirstOrDefault();
htmlContext = htmlContext.Replace("{{SHOPINGNAME}}", entity.ShopingName);
htmlContext = htmlContext.Replace("{{SHOPINGPric}}", entity.ShopingPric.ToString());
htmlContext = htmlContext.Replace("{{SHOPINGNuber}}", entity.ShopingCount.ToString());
return htmlContext;
}

 

接下了就是控制器 的调用了

public FileResult ExportPDF()
{
string htmlContext = System.IO.File.ReadAllText(Server.MapPath("~/HTMLTemplate/ShopingBuy.html"));
var context= _iShopingServer.Placeholderfill(htmlContext);
PDFHelp pf = new PDFHelp();
var ms= pf.ConvertHtmlTextToPDF(context);
return File(ms,"application/pdf", "shoping"+ DateTime.Now+ ".pdf");
}

 

在页面上写个点击PDF下载的按钮 Ajax 调用这个方法  然后就是最终实现的效果。 写的很粗糙。 但实现的过程还是比较容易的。

一般业务都是转PDF然后加入邮箱附件 用来发邮件的。 

这里只是简单实现。  有时间还得继续深入研究

 

 

 

 

 

 

 

 

ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下

先简单了解一这个几个 名词的意思。

控制反转(IOC) 依赖注入(DI) 并不是某种技术。 而是一种思想。一种面向对象编程法则

 

什么是控制反转(IOC)?  什么是依赖注入(DI)

可以点击下面链接 理解的比较详细 

https://blog.csdn.net/PacosonSWJTU/article/details/52786216

https://www.cnblogs.com/Mr-Rocker/p/7721824.html

 

控制反转(IOC)

在之前传统应用程序 我们都是在类内部主动实例化依赖对象,从而导致类与类之间高耦合,难于测试

可以看到下图类与类之间 依赖关系很紧密

(图是我盗的。感谢做这个图的大佬)

 

IOC 就是一种容器  把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

IOC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

 

依赖注入(DI) 

 依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台

依赖谁?   依赖于IOC容器

注入谁 ?   由IoC容器注入应用程序某个对象,应用程序依赖的对象

 被依赖者并不是有依赖者主动去初始化     而是有提供资源的外部创建者决定

 两者关系也就是   被注入对象依赖IoC容器配置依赖对象

 

说到DI IOC 就有必要了解下 现在用的最多的AutoFac

 

首先在项目中引入 AutoFac    如果你是WebAPI   你可以输入 AutoFac.WebApi2 

 

 

 

我定义了 两个仓储类   IRepositoryBase  和 RepositoryBase  主要用于操作数据库的各种方法

public interface IRepositoryBase<T> where T:class
{

IQueryable<T> FindAll();

T FindSingle(Expression<Func<T, bool>> exp = null);

T Find(int id);

IQueryable<T> Find(Expression<Func<T, bool>> exp = null);

/// <summary>
/// Linq表达式树查询分页
/// </summary>
/// <returns></returns>
IQueryable<T> Find(int pageindex = 1, int pagesize = 10, Expression<Func<T, bool>> exp = null);

/// <summary>
/// 得到受影响条数
/// </summary>
/// <returns></returns>
int GetCount(Expression<Func<T, bool>> exp = null);

void Add(T entity);

void AddBatch(T[] entitys);

void AddBatch(List<T> entitys);

/// <summary>
/// 更新实体所有属性
/// </summary>
/// <returns></returns>
void Update(T entity);

void Delete(T entity);

/// <summary>
/// 按指定的ID进行批量更新
/// </summary>
void Update(Expression<Func<T, object>> identityExp,T entity);

T Update(T entity,int id);

/// <summary>
/// 批量删除
/// </summary>
void Delete(Expression<Func<T, bool>> exp);

void Save();

int ExecuteSql(string sql);
}

 

继承接口并实现

public class RepositoryBase<T> : IRepositoryBase<T> where T:class
{
protected OpenSPDBContext openSPDBContext = new OpenSPDBContext();

public void Add(T entity)
{
openSPDBContext.Set<T>().Add(entity);
Save();
}

public void AddBatch(T[] entitys)
{
openSPDBContext.Set<T>().AddRange(entitys);
Save();
}

public void Delete(Expression<Func<T, bool>> exp)
{
var entitys= openSPDBContext.Set<T>().Where(exp);
openSPDBContext.Set<T>().RemoveRange(entitys);
}

public void Delete(T entity)
{
openSPDBContext.Set<T>().Remove(entity);
Save();
}

public int ExecuteSql(string sql)
{
return openSPDBContext.Database.ExecuteSqlCommand(sql);
}

public IQueryable<T> Find(Expression<Func<T, bool>> exp = null)
{
return Filter(exp);
}

public T Find(int id)
{
return openSPDBContext.Set<T>().Find(id);
}

public IQueryable<T> Find(int pageindex, int pagesize, Expression<Func<T, bool>> exp = null)
{

return Filter(exp).Skip(pagesize * (pageindex - 1)).Take(pagesize);
}

public IQueryable<T> FindAll()
{
return openSPDBContext.Set<T>();
}

public T FindSingle(Expression<Func<T, bool>> exp = null)
{
return openSPDBContext.Set<T>().AsNoTracking().FirstOrDefault(exp);
}

public int GetCount(Expression<Func<T, bool>> exp = null)
{
return Filter(exp).Count();
}

public void Update(T entity)
{
openSPDBContext.Entry(entity).State = EntityState.Modified;
Save();
}

/// <summary>
/// 按指定id更新实体,会更新整个实体
/// </summary>
/// <param name="identityExp">The identity exp.</param>
/// <param name="entity">The entity.</param>
public void Update(Expression<Func<T, object>> identityExp, T entity)
{
openSPDBContext.Set<T>().AddOrUpdate(identityExp, entity);
}

public IQueryable<T> Filter(Expression<Func<T,bool>> exp)
{
var dbset = openSPDBContext.Set<T>().AsQueryable();
if (exp != null)
dbset = dbset.Where(exp);

return dbset;

}

public void Save()
{
try
{
openSPDBContext.SaveChanges();
}
catch (DbEntityValidationException e)
{
throw new Exception(e.EntityValidationErrors.First().ValidationErrors.First().ErrorMessage);
throw;
}
}

public void AddBatch(List<T> entitys)
{
openSPDBContext.Set<T>().AddRange(entitys);
}

public T Update(T entity, int id)
{
openSPDBContext.Entry(entity).State = EntityState.Modified;
Save();
return openSPDBContext.Set<T>().Find(id);
}
}

 

然后 在全局类中注册依赖配置

 

我新建了个逻辑处理层 Server  用来方便控制调用   这里我依赖了IRepositoryBase<T>

public class ShopingServer : IShopingServer
{
private IRepositoryBase<ShopingInfo> _shopingRepository;
public ShopingServer(IRepositoryBase<ShopingInfo> shopingRepository)
{
_shopingRepository = shopingRepository;
}

public IQueryable<ShopingInfo> GetAll()
{
var ss = _shopingRepository.FindAll();
return ss;
}
}

 

然后控制器  注入  (这里 我依赖了IRepositoryBase  IShopingServer)  IShopingServer 是我定义的服务类接口 这里我就不贴出来了

我们 分别调用一下 IRepositoryBase   IShopingServer  里面的一个方法 测试一下

 

可以看到 已经注入成功了    小菜也有梦想。 每天一点点 

 

 

 

1、InstancePerDependency

对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。

2、InstancePerLifetimeScope

在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。

3、InstancePerMatchingLifetimeScope

在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。

4、InstancePerOwned

在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。

5、SingleInstance

每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。

6、InstancePerHttpRequest

在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。

 

 

C# AutoMapper 了解一下

什么是AutoMapper?

简单来说就是将一个对象映射到另一个对象的代码。 摆脱了繁琐的赋值过程 (最常见也就是Model -——ViewModel)

 

AutoMapper安装

我使用的是VS2015   可以在NuGet中直接输入AutoMapper 去下载

 

也可以使用控制台命令

PM> Install-Package AutoMapper

 

这里我定义了两个类   ShopingInfo         ShopingInfoViewModel

public class ShopingInfo:EntityBase
{

public string ShopingName { get; set; }

public int ShopingCount { get; set; }

public decimal ShopingPric { get; set; }

public int Stock { get; set; }

public int Volumeofvolume { get; set; }

public int ShopingTypeId { get; set; }

public virtual ShopingType ShopingType { get; set; }
}

 

public class ShopingInfoViewModel
{
public int ID { get; set; }

public string ShopingName { get; set; }

public int ShopingCount { get; set; }

public decimal ShopingPric { get; set; }

public int Stock { get; set; }

public int Volumeofvolume { get; set; }

public string ShopingTypeName { get; set; }
}

 

需要用到的命名空间

using AutoMapper;

 

然后 专门建了一个类用来存放这些映射关系SourceProfile 并且继承了 Profile

public class SourceProfile : Profile
{
public SourceProfile()
{
base.CreateMap<ShopingInfo, ShopingInfoViewModel>();
}
}

如果 我们发现两类中有字段名不一致。 

例如 我吧shopingInfoViewModel 中的 ShopingName  改为  Name    那你可以这样写

public class SourceProfile : Profile
{
public SourceProfile()
{
base.CreateMap<ShopingInfo, ShopingInfoViewModel>();

// base.CreateMap<ShopingInfo, ShopingInfoViewModel>().ForMember(x => x.Name,
//      q => { q.MapFrom(z => z.ShopingName);
//  });
}
}

 

建了个中间类 用来封装上面的代码

public class AutoMapper
{
public static void Start()
{
Mapper.Initialize(x =>
{
x.AddProfile<SourceProfile>();
});
}
}

 

然后就在全局类Global中 使得 启动初始化就去加载 加入下面这句代码

AutoMapper.Start();


好了。 基本的都搞好了。 现在测试一下

可以 看到 已经映射上去了。

如果对多个Profile派生类的AutoMapper有疑问,可以这么写:


其中Dto_StudentProfile,StudentProfile是两个Profile的派生类,写了不同字段名称,不同类型的互相映射,如果还有疑问,可以移步我的博客C#使用AutoMapper6.2.2.0进行对象映射
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐