Skip to content
This repository has been archived by the owner on Apr 19, 2021. It is now read-only.

Commit

Permalink
数据访问组件增加EntityFramework执行sql语句的API与实现
Browse files Browse the repository at this point in the history
  • Loading branch information
gmf520 committed Mar 18, 2015
1 parent c053154 commit ab7346a
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 17 deletions.
66 changes: 66 additions & 0 deletions src/OSharp.Core.Data.Entity/CodeFirstDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// <last-date>2014-07-17 17:34</last-date>
// -----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity;
Expand Down Expand Up @@ -71,6 +73,52 @@ private static bool DataLoggingEnabled
}
}

/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。
/// 您提供的任何参数值都将自动转换为 DbParameter。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @p0", userSuppliedAuthor);
/// 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="transactionalBehavior">对于此命令控制事务的创建。</param>
/// <param name="sql">命令字符串。</param>
/// <param name="parameters">要应用于命令字符串的参数。</param>
/// <returns>执行命令后由数据库返回的结果。</returns>
public int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters)
{
System.Data.Entity.TransactionalBehavior behavior = transactionalBehavior == TransactionalBehavior.DoNotEnsureTransaction
? System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction
: System.Data.Entity.TransactionalBehavior.EnsureTransaction;
return Database.ExecuteSqlCommand(behavior, sql, parameters);
}

/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。 类型可以是包含与从查询返回的列名匹配的属性的任何类型,也可以是简单的基元类型。 该类型不必是实体类型。
/// 即使返回对象的类型是实体类型,上下文也决不会跟踪此查询的结果。 使用 SqlQuery(String, Object[]) 方法可返回上下文跟踪的实体。
/// 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。
/// 您提供的任何参数值都将自动转换为 DbParameter。 unitOfWork.SqlQuery&lt;Post&gt;("SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor);
/// 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 unitOfWork.SqlQuery&lt;Post&gt;("SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <typeparam name="TElement">查询所返回对象的类型。</typeparam>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
{
return Database.SqlQuery<TElement>(sql, parameters);
}

/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定类型的元素。 类型可以是包含与从查询返回的列名匹配的属性的任何类型,也可以是简单的基元类型。 该类型不必是实体类型。 即使返回对象的类型是实体类型,上下文也决不会跟踪此查询的结果。 使用 SqlQuery(String, Object[]) 方法可返回上下文跟踪的实体。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Database.SqlQuery(typeof(Post), "SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Database.SqlQuery(typeof(Post), "SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="elementType">查询所返回对象的类型。</param>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
public IEnumerable SqlQuery(Type elementType, string sql, params object[] parameters)
{
return Database.SqlQuery(elementType, sql, parameters);
}

/// <summary>
/// 提交当前单元操作的更改。
/// </summary>
Expand Down Expand Up @@ -125,6 +173,24 @@ internal int SaveChanges(bool validateOnSaveEnabled)
}
#if NET45

/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。
/// 您提供的任何参数值都将自动转换为 DbParameter。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @p0", userSuppliedAuthor);
/// 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="transactionalBehavior">对于此命令控制事务的创建。</param>
/// <param name="sql">命令字符串。</param>
/// <param name="parameters">要应用于命令字符串的参数。</param>
/// <returns>执行命令后由数据库返回的结果。</returns>
public async Task<int> ExecuteSqlCommandAsync(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters)
{
System.Data.Entity.TransactionalBehavior behavior = transactionalBehavior == TransactionalBehavior.DoNotEnsureTransaction
? System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction
: System.Data.Entity.TransactionalBehavior.EnsureTransaction;
return await Database.ExecuteSqlCommandAsync(behavior, sql, parameters);
}

/// <summary>
/// 异步提交当前单元操作的更改。
/// </summary>
Expand Down
16 changes: 16 additions & 0 deletions src/OSharp.Core.Data.Entity/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// -----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
Expand Down Expand Up @@ -335,6 +336,21 @@ public IQueryable<TEntity> GetIncludes(params string[] paths)
return source;
}

/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回此集中的实体。
/// 默认情况下,上下文会跟踪返回的实体;可通过对返回的 DbRawSqlQuery 调用 AsNoTracking 来更改此设置。 请注意返回实体的类型始终是此集的类型,而不会是派生的类型。 如果查询的一个或多个表可能包含其他实体类型的数据,则必须编写适当的 SQL 查询以确保只返回适当类型的实体。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Set(typeof(Blog)).SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Set(typeof(Blog)).SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="trackEnabled">是否跟踪返回实体</param>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
public IEnumerable<TEntity> SqlQuery(string sql, bool trackEnabled = true, params object[] parameters)
{
return trackEnabled
? _dbSet.SqlQuery(sql, parameters)
: _dbSet.SqlQuery(sql, parameters).AsNoTracking();
}

#if NET45

/// <summary>
Expand Down
10 changes: 10 additions & 0 deletions src/OSharp.Core/Data/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
Expand Down Expand Up @@ -154,6 +155,15 @@ OperationResult Update<TEditDto>(ICollection<TEditDto> dtos,
/// <returns>查询数据集</returns>
IQueryable<TEntity> GetIncludes(params string[] paths);

/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回此集中的实体。
/// 默认情况下,上下文会跟踪返回的实体;可通过对返回的 DbRawSqlQuery 调用 AsNoTracking 来更改此设置。 请注意返回实体的类型始终是此集的类型,而不会是派生的类型。 如果查询的一个或多个表可能包含其他实体类型的数据,则必须编写适当的 SQL 查询以确保只返回适当类型的实体。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Set(typeof(Blog)).SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Set(typeof(Blog)).SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="trackEnabled">是否跟踪返回实体</param>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
IEnumerable<TEntity> SqlQuery(string sql, bool trackEnabled = true, params object[] parameters);
#if NET45
/// <summary>
/// 异步插入实体
Expand Down
47 changes: 47 additions & 0 deletions src/OSharp.Core/Data/IUnitOfWork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// -----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand All @@ -31,6 +32,40 @@ public interface IUnitOfWork : IDependency

#region 方法

/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。
/// 您提供的任何参数值都将自动转换为 DbParameter。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @p0", userSuppliedAuthor);
/// 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="transactionalBehavior">对于此命令控制事务的创建。</param>
/// <param name="sql">命令字符串。</param>
/// <param name="parameters">要应用于命令字符串的参数。</param>
/// <returns>执行命令后由数据库返回的结果。</returns>
int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters);

/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定泛型类型的元素。 类型可以是包含与从查询返回的列名匹配的属性的任何类型,也可以是简单的基元类型。 该类型不必是实体类型。
/// 即使返回对象的类型是实体类型,上下文也决不会跟踪此查询的结果。 使用 SqlQuery(String, Object[]) 方法可返回上下文跟踪的实体。
/// 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。
/// 您提供的任何参数值都将自动转换为 DbParameter。 unitOfWork.SqlQuery&lt;Post&gt;("SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor);
/// 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 unitOfWork.SqlQuery&lt;Post&gt;("SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <typeparam name="TElement">查询所返回对象的类型。</typeparam>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters);

/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回给定类型的元素。 类型可以是包含与从查询返回的列名匹配的属性的任何类型,也可以是简单的基元类型。 该类型不必是实体类型。 即使返回对象的类型是实体类型,上下文也决不会跟踪此查询的结果。 使用 SqlQuery(String, Object[]) 方法可返回上下文跟踪的实体。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Database.SqlQuery(typeof(Post), "SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Database.SqlQuery(typeof(Post), "SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="elementType">查询所返回对象的类型。</param>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
IEnumerable SqlQuery(Type elementType, string sql, params Object[] parameters);

/// <summary>
/// 提交当前单元操作的更改。
/// </summary>
Expand All @@ -39,6 +74,18 @@ public interface IUnitOfWork : IDependency

#if NET45

/// <summary>
/// 对数据库执行给定的 DDL/DML 命令。
/// 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。
/// 您提供的任何参数值都将自动转换为 DbParameter。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @p0", userSuppliedAuthor);
/// 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 unitOfWork.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="transactionalBehavior">对于此命令控制事务的创建。</param>
/// <param name="sql">命令字符串。</param>
/// <param name="paramters">要应用于命令字符串的参数。</param>
/// <returns>执行命令后由数据库返回的结果。</returns>
Task<int> ExecuteSqlCommandAsync(TransactionalBehavior transactionalBehavior, string sql, params object[] paramters);

/// <summary>
/// 异步提交当前单元操作的更改。
/// </summary>
Expand Down
33 changes: 33 additions & 0 deletions src/OSharp.Core/Data/TransactionalBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// -----------------------------------------------------------------------
// <copyright file="TransactionalBehavior.cs" company="OSharp开源团队">
// Copyright (c) 2014-2015 OSharp. All rights reserved.
// </copyright>
// <last-editor>郭明锋</last-editor>
// <last-date>2015-03-18 14:13</last-date>
// -----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace OSharp.Core.Data
{
/// <summary>
/// 在执行数据库命令或查询期间控制事务创建行为。
/// </summary>
public enum TransactionalBehavior
{
/// <summary>
/// 如果存在现有事务,则使用它,否则在没有事务的情况下执行命令或查询。
/// </summary>
DoNotEnsureTransaction,

/// <summary>
/// 如果不存在任何事务,则使用新事务进行操作。
/// </summary>
EnsureTransaction
}
}
Loading

0 comments on commit ab7346a

Please sign in to comment.