EF调用存储过程、函数
一.ef4.1 codeFirst 修改表结构 增加字段等 EF code first需要重新生成库导致数据丢失的问题
说这个问题前 首先先说下 我使用ef4.1 codefirst的目的. 是因为可以有更纯净的POCO 不再有EDMX这些东西 而不是真正的用 code first 先有代码 再生成数据库.所以 我虽然使用
的是codefirst 但是本质依然是数据库优先.
所以这个被问的很多的问题 解决办法其实是非常简单的.只要你的数据库已经存在了 那么即使你用code first ef 也不会给你去生成数据库的. 这个时候 你增加表字段 甚至增加表 只要把
实体类也相应的修改 则数据库里的数据 是不会被清空的.
说下我的开发步骤 先设计数据库 并建立数据库=>通过EF工具生成映射和实体类=>开发代码 当遇到修改时=> 先修改数据库如添加字段或表等=>再修改实体类=>继续开发
这样就不会有重新生成数据的烦恼了 而且项目里也不会出现edmx~
还有 使用EF4.3 的数据迁移功能 也可以完美解决~
二.ef4.1 没有了edmx等复杂的东西 变得简单 干净 但如何使用存储过程,存储过程可以返回表 可以返回数值 也有可能是执行修改 删除 增加等 该怎么做?
说这个问题前 依然先说下我的观点.个人认为 既然使用orm框架 就应该把业务逻辑等 都放到业务逻辑层 而不应该再使用存储过程。我更偏重重业务逻辑层 轻存储过程这样的开发~
再ef4.0里 添加存储过程 比较容易 有edmx 调一调 存储过程就添加上了 但是在ef4.1里 只有干净的poco 不再有edmx了 改怎么办呢?尤其是存储过程可以是查表 查值 或者执行修改删除.
一个一个来解决
1.执行返回表类型的存储过程
先上存储过程 随手写的一个最简单的

Create PROCEDURE [dbo].[ProSelectStu]
@StudentID int
AS
BEGIN
Select Student.* from Enrollment,Student
where Enrollment.StudentID=Student.StudentID and Enrollment.StudentID=@StudentID
END
GO

执行存储过程的方法 是用直接执行sql的方式 我在我的文章第九篇 有过详细的介绍~大家可以先去看下
执行表的存储过程 其实是非常强大的 延迟加载 等都有体现 博客园的陆老师已经写了 写的非常清楚了~我这里就不再写了 大家可以去他那看下 提供个连接~
2.执行返回值的存储过程
先上存储过程
CREATE PROCEDURE [dbo].[ProSelectCount]
@StuId int
AS
BEGIN
select COUNT(*) from Enrollment where StudentID=@StuId
END
一个简单的查询数量
这里用sqlQuery 执行访问 数据库 因为需要提供返回类型 而我们返回的是int 所以先得到int的类型
3.执行增删改

CREATE PROCEDURE [dbo].[ProDel]
@stuId int,
@courseId int
AS
BEGIN
DELETE FROM [WLFSchool].[dbo].[Enrollment]
where StudentID=@stuId and CourseID=@courseId
END

这个用的是操作数据库 返回受影响行数
三.ef4.1 如何使用数据库视图?每个视图都要去建立对应的实体类么?有简单的方法么?
先说下最传统的方法 只需把视图 当成表 建立对应的实体类 然后加到dbcontext 里即可。没什么难度。
再说一个问题 使用linq 有个非常美妙的功能 投影映射 和C#3.0的 匿名函数 让我们很多情况 不需要视图的

from c in classes
from s in students
where c.ClassID == s.ClassID
order by c.CreateTime
select new
{
Name = s.Name,
Age = s.Age,
ClassName = c.ClassName
};

再通过 var result 接受上面的值 这样我们就不用去数据库建视图 不用再建实体类 是不是很省事呢?
如果公司强大的DBA 已经给我们建好了很多视图 是不是就要一个个去写实体类呢?如果你使用的是C#4.0 那么可以用动态的 来解决这个问题~
像下面这样使用 是不是很爽
这个不仅可以查询视图 普通的表 只要是SQL语句 都可以自动生成动态类 让你用~
下面是扩展方法 和 使用Emit 来动态构建 感谢ASP.NET 韋 给的帮助~~

public static class DatabaseExtensions
{
public static IEnumerable SqlQueryForDynamic(this Database db,
string sql,
params object[] parameters)
{
IDbConnection defaultConn = new System.Data.SqlClient.SqlConnection(); return SqlQueryForDynamicOtherDB(db, sql, defaultConn, parameters);
} public static IEnumerable SqlQueryForDynamicOtherDB(this Database db,
string sql,
IDbConnection conn,
params object[] parameters)
{
conn.ConnectionString = db.Connection.ConnectionString; if (conn.State != ConnectionState.Open)
{
conn.Open();
} IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = sql; IDataReader dataReader = cmd.ExecuteReader(); if (!dataReader.Read())
{
return null; //无结果返回Null
} #region 构建动态字段 TypeBuilder builder = DatabaseExtensions.CreateTypeBuilder(
"EF_DynamicModelAssembly",
"DynamicModule",
"DynamicType"); int fieldCount = dataReader.FieldCount;
for (int i = 0; i < fieldCount; i++)
{
//dic.Add(i, dataReader.GetName(i)); //Type type = dataReader.GetFieldType(i); DatabaseExtensions.CreateAutoImplementedProperty(
builder,
dataReader.GetName(i),
dataReader.GetFieldType(i));
} #endregion dataReader.Close();
dataReader.Dispose();
cmd.Dispose();
conn.Close();
conn.Dispose(); Type returnType = builder.CreateType(); if (parameters != null)
{
return db.SqlQuery(returnType, sql, parameters);
}
else
{
return db.SqlQuery(returnType, sql);
}
} public static TypeBuilder CreateTypeBuilder(string assemblyName,
string moduleName,
string typeName)
{
TypeBuilder typeBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName(assemblyName),
AssemblyBuilderAccess.Run).DefineDynamicModule(moduleName).DefineType(typeName,
TypeAttributes.Public);
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
return typeBuilder;
} public static void CreateAutoImplementedProperty(
TypeBuilder builder,
string propertyName,
Type propertyType)
{
const string PrivateFieldPrefix = "m_";
const string GetterPrefix = "get_";
const string SetterPrefix = "set_"; // Generate the field.
FieldBuilder fieldBuilder = builder.DefineField(
string.Concat(
PrivateFieldPrefix, propertyName),
propertyType,
FieldAttributes.Private); // Generate the property
PropertyBuilder propertyBuilder = builder.DefineProperty(
propertyName,
System.Reflection.PropertyAttributes.HasDefault,
propertyType, null); // Property getter and setter attributes.
MethodAttributes propertyMethodAttributes = MethodAttributes.Public
| MethodAttributes.SpecialName
| MethodAttributes.HideBySig; // Define the getter method.
MethodBuilder getterMethod = builder.DefineMethod(
string.Concat(
GetterPrefix, propertyName),
propertyMethodAttributes,
propertyType,
Type.EmptyTypes); // Emit the IL code.
// ldarg.0
// ldfld,_field
// ret
ILGenerator getterILCode = getterMethod.GetILGenerator();
getterILCode.Emit(OpCodes.Ldarg_0);
getterILCode.Emit(OpCodes.Ldfld, fieldBuilder);
getterILCode.Emit(OpCodes.Ret); // Define the setter method.
MethodBuilder setterMethod = builder.DefineMethod(
string.Concat(SetterPrefix, propertyName),
propertyMethodAttributes,
null,
new Type[] { propertyType }); // Emit the IL code.
// ldarg.0
// ldarg.1
// stfld,_field
// ret
ILGenerator setterILCode = setterMethod.GetILGenerator();
setterILCode.Emit(OpCodes.Ldarg_0);
setterILCode.Emit(OpCodes.Ldarg_1);
setterILCode.Emit(OpCodes.Stfld, fieldBuilder);
setterILCode.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterMethod);
propertyBuilder.SetSetMethod(setterMethod);
} }

四.ef4.1 如何执行SQL函数等操作?
添加引用 System.Data.Objects.SqlClient.SqlFunctions 主要是这个命名空间
使用方法~上一个工作中的例子~
var query = from s in student.T_StudentInfo
where SqlFunctions.DateDiff("day", s.CreateTime, "2011/11/4") == 0
select s.StudentName;
使用SQL 的datadiff 函数~~
EF调用存储过程、函数的更多相关文章
- 转:EF调用存储过程、函数
EF调用存储过程.函数 2014-04-02 09:12:20| 分类: ORM框架|举报|字号 订阅 一.ef4.1 codeFirst 修改表结构 增加字段等 EF code ...
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法
一. 背景 上一个章节,介绍了EF调用两类SQL语句,主要是借助 ExecuteSqlCommand 和 SqlQuery 两个方法来完成,在本章节主要是复习几类存储过程的写法和对应的EF调用这几类 ...
- OTL调用存储过程/函数及注意事项
OTL 是 Oracle, Odbc and DB2-CLI Template Library 的缩写,是一个 C++ 编译中操控关系数据库的模板库,它目前几乎支持所有的当前各种主流数据库. OTL ...
- EF调用存储过程查询表中的部分字段,报数据读取器与指定的“AdventureWorksDWModel.Student”不兼容。某个类型为“Age”的成员在同名的数据读取器中没有对应的列。
实现功能:查询单张表Student中返回指定的列 一:数据库表结构: 二:存储过程: USE [AdventureWorksDW] GO /****** Object: StoredProcedure ...
- 关于MVC 中EF调用存储过程
Entity Framework 4.3 中使用存储过程 分类:ASP.NET MVC 3, ASP.NET 0 尽管 Entit ...
- .NET MVC+ EF+调用存储过程 多表联查以及VIEW列表显示
直接上干活,至于网上的一大堆处理方式不予评论,做好自己的就是最好的,供大家不走弯路 1.view页面 <link href="~/Content/bootstrap.css" ...
- 关于EF调用存储过程那点事...
最近研究了下EF怎么调用 数据库的分页存储过程,发现还是很不错的 1.数据库存储过程如下,一个简单的不含条件判断的 2.然后新建数据模型中选择存储过程: : 3.EF会自动生存一个返回复杂类型(Obj ...
- EF调用存储过程实例
创建实体: public class User { public string UserID { get; set; } public string UserName { get; set; } pu ...
随机推荐
- 无法对数据库'XXX' 执行删除,因为它正用于复制"的解决方
困扰二天的问题终于得以解决,貌似一个棘手的问题只要知道方法也似乎变得异常简单,记录此次的解决方法,避免遗忘. 无法对 数据库'UDS' 执行 删除,因为它正用于复制. (.Net SqlClient ...
- hadoop文件系统与I/O流
本文地址:http://www.cnblogs.com/archimedes/p/hadoop-filesystem-io.html,转载请注明源地址. hadoop借鉴了Linux虚拟文件系统的概念 ...
- 【转】vim折叠功能
原文:https://www.yupengsir.com/topic/content?i=140 这个作者的vim系列是高级的用法, 要学习一下. https://blog.easwy.com/arc ...
- Unable to create requested service org.hibernate.cache.spi.RegionFactory
hibernate 4.3.11+struts2.3.28.1+spring 4.2.5,在搭框架的时候,报的这个错误: Unable to create requested service org. ...
- STL - 常用关联容器代码 - set & multiset
代码如下: /* 5. set & multiset */ set<string> cities{ "Braunschweig", "Hanover& ...
- xcode 调试程序 lldb 使用
xcode 调试程序 lldb 使用 一:lldb是什么 https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/g ...
- Laravel 教程 - Web 开发实战入门 ( Laravel 5.5 )购买链接
Laravel 教程 - Web 开发实战入门 ( Laravel 5.5 )购买链接: 推荐给你高品质的实战课程 https://laravel-china.org/courses?rf=158 ...
- 如何阅读Android系统源码-收藏必备
对于任何一个对Android开发感兴趣的人而言,对于android系统的学习必不可少.而学习系统最佳的方法就如linus所言:"RTFSC"(Read The Fucking So ...
- js获取事件源及触发该事件的对象
怎样获取事件源及触发该事件的对象,方法有非常多,js中能够通过event来实现.以下有个不错的演示样例,感兴趣的朋友能够參考下: function myfunction(event) { event ...
- java 判断日期是否是节假日
1.新建一个excel命名为“节假日.xls”存放节假日,模板格式如下 2.判断是否是节假日的类 工作日返回true ,休息日返回false. 需要引用poi-bin-3.9包,包放在博客文件中 im ...