让ADO.NET Entity Framework 支持ACCESS数据库
如写的不好请见谅,本人水平有限。
个人简历及水平:。 http://www.cnblogs.com/hackdragon/p/3662599.html
接到一个程序和网页交互的项目,用ADO.NET Entity Framework (以下简称EF)很快就搞完了,但是对方的空间提供的MSSQL数据库比较昂贵,所以就采用ACCESS数据库,但是我查了资料发现 EF不支持Access数据库,(以前觉得LINQ TO SQL 不支持 这个应该支持),写完的代码不想用OLEDB在写了,于是网上一顿查,试验了ALINQ和其他很多的,总是不能符合项目的需要。不是更新不行就算插入失败,要不就是经常查询错误。最后没办法,我自己决定写一个实体支持ACCESS数据库,我觉得懒人应该有需要这个的,当然大侠们估计有更好的办法来更懒一些。
懒人第一步:
因为VS的实体生成器不支持ACCESS数据库,所以无法生成代码,但是想快速开发项目,那么你可以用SQL数据库先来设计,然后导出数据库到ACCESS数据库,这样做的目的是让生成器可以生成我们所需要的代码。注意设计数据库字段的时候要考虑他们的兼容性。
勤快第二步:
开始写代码了,原始的上下文代码如下:
#region 上下文 /// <summary>
/// 没有元数据文档可用。
/// </summary>
public partial class SqlDoorEntities1 : ObjectContext
{
#region 构造函数 /// <summary>
/// 请使用应用程序配置文件的“SqlDoorEntities1”部分中的连接字符串初始化新 SqlDoorEntities1 对象。
/// </summary>
public SqlDoorEntities1() : base("name=SqlDoorEntities1", "SqlDoorEntities1")
{
OnContextCreated();
} /// <summary>
/// 初始化新的 SqlDoorEntities1 对象。
/// </summary>
public SqlDoorEntities1(string connectionString) : base(connectionString, "SqlDoorEntities1")
{
OnContextCreated();
} /// <summary>
/// 初始化新的 SqlDoorEntities1 对象。
/// </summary>
public SqlDoorEntities1(EntityConnection connection) : base(connection, "SqlDoorEntities1")
{
OnContextCreated();
} #endregion #region 分部方法 partial void OnContextCreated(); #endregion #region ObjectSet 属性 /// <summary>
/// 没有元数据文档可用。
/// </summary>
public ObjectSet<CmdMsg> CmdMsg
{
get
{
if ((_CmdMsg == null))
{
_CmdMsg = base.CreateObjectSet<CmdMsg>("CmdMsg");
}
return _CmdMsg;
}
}
private ObjectSet<CmdMsg> _CmdMsg; /// <summary>
/// 没有元数据文档可用。
/// </summary>
public ObjectSet<Door> Door
{
get
{
if ((_Door == null))
{
_Door = base.CreateObjectSet<Door>("Door");
}
return _Door;
}
}
private ObjectSet<Door> _Door; /// <summary>
/// 没有元数据文档可用。
/// </summary>
public ObjectSet<Manager> Manager
{
get
{
if ((_Manager == null))
{
_Manager = base.CreateObjectSet<Manager>("Manager");
}
return _Manager;
}
}
private ObjectSet<Manager> _Manager; /// <summary>
/// 没有元数据文档可用。
/// </summary>
public ObjectSet<Users> Users
{
get
{
if ((_Users == null))
{
_Users = base.CreateObjectSet<Users>("Users");
}
return _Users;
}
}
private ObjectSet<Users> _Users; #endregion #region AddTo 方法 /// <summary>
/// 用于向 CmdMsg EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
/// </summary>
public void AddToCmdMsg(CmdMsg cmdMsg)
{
base.AddObject("CmdMsg", cmdMsg);
} /// <summary>
/// 用于向 Door EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
/// </summary>
public void AddToDoor(Door door)
{
base.AddObject("Door", door);
} /// <summary>
/// 用于向 Manager EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
/// </summary>
public void AddToManager(Manager manager)
{
base.AddObject("Manager", manager);
} /// <summary>
/// 用于向 Users EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
/// </summary>
public void AddToUsers(Users users)
{
base.AddObject("Users", users);
} #endregion } #endregion
ObjectContext 继承于IDisposable 那么我写一个自己的 ObjectContext 这样的类 我给他起个名字叫EFToAccess 那么多 构造方法 我们就需要2个一个 是 给定的连接字符串 一个是默认从webconfig中读取的链接字符串就可以了。本人偷懒,直接读取指定的路径了。数据库的简单读写可能都依赖一个where查询,那么怎么实现自己的where查询就很关键,于是我看资料研究了2天Lambda Expression 表达式。最后还是看了 博客园的一篇 扩展LINQ to SQL:使用Lambda Expression批量删除数据才会用,现在也不是很明白,懒人就是拿来主义,不怎么消化,我现在也没多少时间消化知识,估计这样的人也不少吧。下面是我自己用的的方法,利用VS生成的代码 2个替换1个删除搞定 (ObjectContext替换“你自己的类名我的是SqlDoorEntities”,ObjectSet替换成IEnumerable,删除无用的构造函数)
public class SqlDoorEntities : EFToAccess
{
public SqlDoorEntities():base("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+AppDomain.CurrentDomain.BaseDirectory + "bin\\DataDoor.mdb")
{
}
#region IEnumerable 属性
/// <summary>
/// 没有元数据文档可用。
/// </summary> public IEnumerable<CmdMsg> CmdMsg
{
get
{
if ((_CmdMsg == null))
{
_CmdMsg = base.CreateObjectSet<CmdMsg>("CmdMsg");
}
return _CmdMsg;
}
}
private IEnumerable<CmdMsg> _CmdMsg; /// <summary>
/// 没有元数据文档可用。
/// </summary>
public IEnumerable<Door> Door
{
get
{
if ((_Door == null))
{
_Door = base.CreateObjectSet<Door>("Door");
}
return _Door;
}
}
private IEnumerable<Door> _Door; /// <summary>
/// 没有元数据文档可用。
/// </summary>
public IEnumerable<Manager> Manager
{
get
{
if ((_Manager == null))
{
_Manager = base.CreateObjectSet<Manager>("Manager");
}
return _Manager;
}
}
private IEnumerable<Manager> _Manager; /// <summary>
/// 没有元数据文档可用。
/// </summary>
public IEnumerable<Users> Users
{
get
{
if ((_Users == null))
{
_Users = base.CreateObjectSet<Users>("Users");
}
return _Users;
}
}
private IEnumerable<Users> _Users; #endregion
#region AddTo 方法 /// <summary>
/// 用于向 CmdMsg EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
/// </summary>
public void AddToCmdMsg(CmdMsg cmdMsg)
{
base.AddObject("CmdMsg", cmdMsg);
} /// <summary>
/// 用于向 Door EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
/// </summary>
public void AddToDoor(Door door)
{
base.AddObject("Door", door);
} /// <summary>
/// 用于向 Manager EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
/// </summary>
public void AddToManager(Manager manager)
{
base.AddObject("Manager", manager);
} /// <summary>
/// 用于向 Users EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
/// </summary>
public void AddToUsers(Users users)
{
base.AddObject("Users", users);
} #endregion
}
懒人第三步:
为了让代码和EF使用方法基本一致,所以不得不做一些工作让我写的类基本满足项目需要。首先实现一个让Lambda Expression 表达式变成字符串的函数
string GetWhereString(Expression Func)
{
ConditionBuilder conditionBuilder = new ConditionBuilder();
conditionBuilder.Build(Func);
for (int i = ; i < conditionBuilder.Arguments.Length; i++)
{
object ce = conditionBuilder.Arguments[i];
if (ce == null)
conditionBuilder.Arguments[i] = "null";
else if (ce is ValueType)
conditionBuilder.Arguments[i] = ce.ToString();
else if (ce is string || ce is char)
conditionBuilder.Arguments[i] = string.Format("'{0}'", ce.ToString());
else if (ce is DateTime)
conditionBuilder.Arguments[i] = string.Format("#{0}#", ce.ToString()); }
return string.Format(conditionBuilder.Condition, conditionBuilder.Arguments);
}
上面的ConditionBuilder类代码我就不贴出了。大家参考我提到的那篇文章,如果实际应用当中,有死循环的地方那么应该在该调用基类的地方加入base.XXX比如base.Visit
实现我们自己的where 这里如果我们自己生成类 那么我们的实体类类可以直接有一个where 方法,但是我为了能让我们懒人使用VS生成的实体类只能这么实现了。为了代码利用率,我们还需要另外2个函数。
取得所有记录
IEnumerable<TEntity> SelectAll<TEntity>() where TEntity : new()
{
TEntity TDefault = new TEntity();
string entitySetName = TDefault.GetType().Name;
string strSqlQuery = string.Format("SELECT * FROM {0}", entitySetName);
m_LastSqlCommand = strSqlQuery;
return SelectWhere<TEntity>(strSqlQuery);
}
经常的条件查询
public IEnumerable<TEntity> Where<TEntity>(Expression<Func<TEntity, bool>> Func) where TEntity : new()
{
TEntity TDefault = new TEntity();
string entitySetName = TDefault.GetType().Name;
string strWhere = GetWhereString(Func).Replace("Where", entitySetName);
string strSqlQuery = string.Format("SELECT * FROM {0} WHERE {1} ", entitySetName, strWhere);
m_LastSqlCommand = strSqlQuery;
return SelectWhere<TEntity>(strSqlQuery);
}
最后的where
IEnumerable<TEntity> SelectWhere<TEntity>(string strSqlQuery) where TEntity : new()
{
TEntity TDefault = new TEntity();
//确认基础类型是否是 EntityObject类型
Type TBase = TDefault.GetType();
while ((TBase.BaseType) != null)
{
if (TBase.Name == "EntityObject") break;
TBase = TBase.BaseType;
}
bool IsPCEH = false;
if (TBase != null && TBase.Name == "EntityObject") IsPCEH = true;
PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
List<TEntity> Records = new List<TEntity>();
string entitySetName = TDefault.GetType().Name;
try
{
OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
OleDbDataReader sqlReader = Cmd.ExecuteReader();
#region 数据库查询开始
while (sqlReader.Read())
{
TEntity TValue = new TEntity();
//输入是EntityObject类型,那么加入属性改变事件
if (IsPCEH)
{
EntityObject EO = TValue as EntityObject;
EO.PropertyChanged += PropertyChangedEH;
}
for (int i = ; i < sqlReader.FieldCount; i++)
{
string strField = sqlReader.GetName(i);
//根据字段名 反射 类的属性
PropertyInfo p = properties.Where(P => string.Compare(P.Name, strField, true) == ).First();
#region 数据转换
switch (p.PropertyType.Name.ToString().ToLower())
{
case "int16":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetInt16(i), null);
break;
case "int32":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetInt32(i), null);
break;
case "int64":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetInt64(i), null);
break;
case "string":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetString(i), null);
break;
case "double":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetDouble(i), null);
break;
case "float":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetFloat(i), null);
break;
case "decimal":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetDecimal(i), null);
break;
case "datetime":
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetDateTime(i), null);
break;
default:
if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetValue(i), null);
break;
}
#endregion }
Records.Add(TValue);
}
#endregion
Cmd.Clone();
m_IsDetectionChange = true;
}
catch (Exception)
{
throw;
}
return Records;
}
属性的改变(也就是数据库记录的字段值)我们要知道才能实现EF的SaveChanges()函数那么我们需要简历一个数组变量,直接上代码
//表名 //主键 //属性 值1 值2 主键类型名字
Dictionary<string, Dictionary<string, Dictionary<string, object[]>>> m_ArrDetection = new Dictionary<string, Dictionary<string, Dictionary<string, object[]>>>();
void PropertyChangedEH(object sender, PropertyChangedEventArgs e)
{
//没有开启返回
if (!m_IsDetectionChange) return;
//反射所有属性
PropertyInfo[] properties = sender.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
//查询主键
PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
//没有主键的返回(表必须要有主键)
if (EntityKey == null) return;
//表名字
string Table = sender.GetType().Name;
//主键值
string MainKey = EntityKey.GetValue(sender, null).ToString();
if (MainKey == null || MainKey == "") return;
//没有表 就添加
if (!m_ArrDetection.ContainsKey(Table)) m_ArrDetection[Table] = new Dictionary<string, Dictionary<string, object[]>>();
//没有主键 就添加
if (!m_ArrDetection[Table].ContainsKey(MainKey)) m_ArrDetection[Table][MainKey] = new Dictionary<string, object[]>();
//主键是不用更新的(一般数据库主键都是自动增长的吧,尤其快速开发的项目)
if (e.PropertyName == MainKey) return;
PropertyInfo p = properties.Where(P => string.Compare(P.Name, e.PropertyName, true) == ).First();
//赋值
m_ArrDetection[Table][MainKey][e.PropertyName] = new object[] { p.GetValue(sender, null), EntityKey.Name };
}
查找主键的函数
private bool IsEntityKeyProperty(PropertyInfo Info)
{
foreach (Attribute attr in Attribute.GetCustomAttributes(Info))
{
if (attr is System.Data.Objects.DataClasses.EdmScalarPropertyAttribute)
{
System.Data.Objects.DataClasses.EdmScalarPropertyAttribute Key = (System.Data.Objects.DataClasses.EdmScalarPropertyAttribute)attr;
if (Key.EntityKeyProperty == true)
{
return true;
}
}
}
return false;
}
private PropertyInfo GetEntityKeyFormAllProperty(PropertyInfo[] properties)
{
foreach (PropertyInfo Info in properties)
{
if (IsEntityKeyProperty(Info)) return Info;
}
return null;
}
在实际的调用过程中,我们使用基本可以和EF使用一样
public ActionResult Index()
{
int UID = GetUerID();
List<Door> Arr = new List<Door>();
try
{
// TODO: Add insert logic here
using (SqlDoorEntities Database = new SqlDoorEntities())
{
//EF写法
//IEnumerable<Door> Records = Database.Door.Where(R => R.U_ID == UID);
IEnumerable<Door> Records = Database.Where<Door>(R => R.U_ID == UID);
foreach (Door Record in Records) Arr.Add(Record);
} }
catch (Exception E)
{
return Content(E.Message);
}
return View(Arr);
}
当然你可以直接用EF的方式 ,缺点就是直接把整个表的数据都读取过来了。下面我依次说说 数据库的 增加 删除 修改;
增加
实现CreateObjectSet,懒人嘛,要不还得去修改。
public IEnumerable<TEntity> CreateObjectSet<TEntity>(string entitySetName) where TEntity : new()
{
return SelectAll<TEntity>();
}
实现AddObject 直接一个简单把对象插入到数组中。实现的时候可以让SaveChanges()在处理
List<object> m_ArrAdd = new List<object>();
public void AddObject(string strName, object o)
{
m_ArrAdd.Add(o);
}
总说SaveChanges()那么先把他贴出来
public int SaveChanges()
{
if (m_ArrDel.Count > )
{
DeleteAll();
m_ArrDel.Clear();
}
if (m_ArrAdd.Count > )
{
AddAll();
m_ArrAdd.Clear();
}
if (m_ArrDetection.Count > )
{
AutoUpdate();
m_ArrDetection.Clear();
}
m_IsDetectionChange = false;
return ;
}
其实也没什么,就是看看数组中哪个有了需要增删改的 就处理下,接着写添加所有的函数。
int AddAll()
{
foreach (object O in m_ArrAdd)
{
AddNew(O);
}
return ;
}
下面该实现我们的insert into 了 直接使用也是可以的 就不用使用纠结的SaveChanges()了。
public int AddNew<TEntity>(TEntity TDefault) where TEntity : class
{
PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
string TabName = TDefault.GetType().Name;
string EntityValue = "";
string strRows = "";
string strValues = "";
#region Rows Values
foreach (PropertyInfo Info in properties)
{
object ce = Info.GetValue(TDefault, null);
string strLeft = Info.Name;
string strRight = "";
if (ce == null)
continue;
else if (ce is DateTime)
strRight = string.Format("#{0}#", ce.ToString());
else if (ce is ValueType)
strRight = ce.ToString();
else if (ce is ValueType)
strRight = ce.ToString();
else if (ce is string || ce is char)
strRight = string.Format("'{0}'", ce.ToString());
if (strLeft == EntityKey.Name)
{
EntityValue = strRight;
continue;
}
if (strRight.Length == ) continue;
if (strLeft == "EntityKey" || strLeft == "EntityState") continue;
strRows = strRows + strLeft + ",";
strValues = strValues + strRight + ",";
}
#endregion
if (strRows.Length < || strValues.Length < ) throw new Exception("SQL语句错误");
strRows = strRows.Remove(strRows.Length - );
strValues = strValues.Remove(strValues.Length - );
string strSqlQuery = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", TabName, strRows, strValues);
m_LastSqlCommand = strSqlQuery;
try
{
OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
Cmd.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
return ;
}
函数中也没什么,就是注意一下不要生成SQL语句的时候,把主键信息也生成进去,一般情况主键大多是个自动增长的数字吧。还有就是不要把EntityObject的属性的特有主键信息写入到数据库中。根据反射写入数据库。
删除
还是先现实EF的删除方法DeleteObject
public void DeleteObject(object TDefault)
{
PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
string EntityValue = EntityKey.GetValue(TDefault, null).ToString();
if (EntityValue == null || EntityValue == "") throw new Exception("反射取值失败!");
string entitySetName = TDefault.GetType().Name;
string KeyName = TDefault.GetType().Name;
if (!m_ArrDel.ContainsKey(KeyName)) m_ArrDel.Add(KeyName,new List<string>());
m_ArrDel[KeyName].Add(string.Format("(({0})={1})", EntityKey.Name, EntityValue));
}
然后我们需要建立我们自己的列表
Dictionary<string, List<string>> m_ArrDel = new Dictionary<string, List<string>>();
实现删除函数
public int Delete<TEntity>(TEntity TDefault)
{
PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
string EntityValue = EntityKey.GetValue(TDefault, null).ToString();
if (EntityValue == null || EntityValue == "") throw new Exception("反射取值失败!");
string entitySetName = TDefault.GetType().Name;
string strSqlQuery = string.Format("DELETE FROM {0} WHERE {1}={2} ", entitySetName, EntityKey, EntityValue);
m_LastSqlCommand = strSqlQuery;
try
{
OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
Cmd.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
return ;
}
更新
这里是根据主键更新的,没有实现update …where…,因为往往都是查询到记录,然后根据这个记录更新的,所以还需要更多代码的实现Select等,为了这个小的项目进度没有写完。上面代码已经告诉了,可以侦测到查询到的属性的变更所以SaveChanges()保存更改时,我们就直接根据数组进行更改了。
public int AutoUpdate()
{
List<string> ArrSqlText = new List<string>();
foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, object[]>>> TabKVP in m_ArrDetection)
{
//遍历表名
string TabName = TabKVP.Key;
foreach (KeyValuePair<string, Dictionary<string, object[]>> KeyKVP in TabKVP.Value)
{
string strSet = "";
string strMainKeyName = "";
#region 把数据列出来例如: a=1,c="2"
foreach (KeyValuePair<string, object[]> ValueKVP in KeyKVP.Value)
{
if (strMainKeyName.Length == ) strMainKeyName = ValueKVP.Value[].ToString();
object Va = ValueKVP.Value[];
string strLeft = ValueKVP.Key;
string strRight = "";
#region 根据值确认是否添加引号
if (ValueKVP.Value == null)
continue;
else if (Va is DateTime)
strRight = string.Format("#{0}#", Va.ToString());
else if (Va is ValueType)
strRight = Va.ToString();
else if (Va is string || Va is char)
strRight = string.Format("'{0}'", Va.ToString());
#endregion
if (strRight.Length == ) continue;
if (strLeft == "EntityKey" || strLeft == "EntityState") continue;
strSet += strLeft + "=" + strRight + ","; }
#endregion
if (strSet.Length < ) continue;
strSet = strSet.Remove(strSet.Length - );
//根据当前的主键[ID] 生成一个SQL语句
string strSqlQuery = string.Format("UPDATE {0} SET {1} WHERE {2}={3} ", TabName, strSet, strMainKeyName, KeyKVP.Key);
ArrSqlText.Add(strSqlQuery);
}
}
foreach (string strSqlQuery in ArrSqlText)
{
m_LastSqlCommand = strSqlQuery;
try
{
OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
Cmd.ExecuteNonQuery();
}
catch
{
} }
return ;
}
当然我们还有直接把对象直接赋值拷贝的时候( a = b),这时候是侦测不到属性的变化的,所以我们要另外一个函数来支持更新,就是让他实现侦测到属性的变化。
public void CopyPropertiesFrom(object destObject, object sourceObject)
{
if (destObject.GetType().Name != destObject.GetType().Name) throw new Exception("类型不同");
PropertyInfo[] destProperties = destObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo[] sourceProperties = sourceObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo EntityKey = GetEntityKeyFormAllProperty(destProperties);
if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!"); for (int i = ; i < destProperties.Length; i++)
{
if (destProperties[i]==null|| destProperties[i].Name == EntityKey.Name) continue;
if (destProperties[i].Name == "EntityKey" || destProperties[i].Name == "EntityState") continue;
object DstV = destProperties[i].GetValue(destObject,null);
object SrcV = sourceProperties[i].GetValue(sourceObject, null);
if (SrcV == null) continue;//源 是NULL 不拷贝
if (DstV.ToString() == SrcV.ToString()) continue;
destProperties[i].SetValue(destObject, SrcV,null);
//Action<object, object> LmdSetProp = LmdSet(destObject.GetType(), destProperties[i].Name);
//LmdSetProp(destObject, SrcV);
} }
显示-添加-删除-修改的例子代码
#region 显示用户
[Authorize(Roles = "manager")]
public ActionResult Index()
{
List<Users> Users = new List<Users>();
Users u = new Users();
try
{
using (SqlDoorEntities Database = new SqlDoorEntities())
{
IEnumerable<Users> Records = Database.Users;
if (Records.Count() > )
{
foreach (Users U in Records) Users.Add(U);
}
}
}
catch { }
return View(Users);
}
#endregion #region 创建用户
[Authorize(Roles = "manager")]
[HttpPost]
public ActionResult CreateUser(Users collection)
{
try
{
// TODO: Add insert logic here
using (SqlDoorEntities Database = new SqlDoorEntities())
{
IEnumerable<Users> Records = Database.Where<Users>(R => R.U_Number == collection.U_Number);
if (Records.Count() > )
{
ModelState.AddModelError("", "已經有了記錄了!");
return RedirectToAction("Index");
}
Database.AddToUsers(collection);
Database.SaveChanges();
//collection.U_LastIP = GetWebClientIp();
}
return RedirectToAction("Index");
}
catch (Exception E)
{
ModelState.AddModelError("", "数据库错误!" + E.Message);
}
return View();
}
[Authorize(Roles = "manager")]
public ActionResult CreateUser()
{
return View();
}
#endregion #region 编辑用户
[Authorize(Roles = "manager")]
[HttpPost]
public ActionResult EditUser(int id, Users collection)
{
try
{
// TODO: Add insert logic here using (SqlDoorEntities Database = new SqlDoorEntities())
{
Users Record = Database.Where<Users>(R => R.U_ID == id).FirstOrDefault();
//Database.Update<Users>(Record);
Database.CopyPropertiesFrom(Record, collection);
Database.SaveChanges();
}
return Content("OK");
}
catch (Exception E)
{
return Content(E.Message);
}
}
#endregion #region 删除用户
[Authorize(Roles = "manager")]
public ActionResult DeleteUser(int id)
{
try
{
// TODO: Add insert logic here using (SqlDoorEntities Database = new SqlDoorEntities())
{
Users Record = Database.Where<Users>(R => R.U_ID == id).FirstOrDefault();
if (User != null)
{
Database.DeleteObject(Record);
Database.SaveChanges();
}
}
}
catch
{ }
return RedirectToAction("Index");
}
#endregion
最后
算是写完了,也算是我cnblog的第一篇技术类文章吧。写的不对的地方欢迎指正啊。本人QQ78486367。下面是用到的源文件。
http://files.cnblogs.com/hackdragon/EFToAccess.zip
让ADO.NET Entity Framework 支持ACCESS数据库的更多相关文章
- [VSTS]让ADO.NET Entity Framework支持Oracle数据库(转载)
近期由于项目所需不得不研究Oracle数据库,回想上一次用Oracle还是07年的事情,实习时候做华晨宝马的项目简单接触了Oracle.这次的项目需要基于.NET平台,我个人的习惯是能用微软自带的就不 ...
- 让ADO.NET Entity Framework支持Oracle数据库
Oracle最近发布了 Oracle Data Access Component(ODAC)11. 2 Rel 4,其中增加了对 Entity Framework 4.1 和4.2的支持.这让 .NE ...
- 让Entity Framework支持MySql数据库(转载)
转载地址:http://www.cnblogs.com/wintersun/archive/2010/12/12/1903861.html Entity Framework 4.0 也可以支持大名鼎鼎 ...
- 读书笔记之ado.net entity framework
提供了对数据访问的一种抽象层,是更加易于以编程的方式来操作及管理数据 有以下几种模式:Model First, Database First, and Code First 现在主要讨论code Fi ...
- ADO.NET Entity Framework
ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案, 早期被称为 ObjectSpace,现已经包含在 V ...
- Microsoft SQL Server Compact 4.0&&ADO.NET Entity Framework 4.1&&MVC3
最近重新查看微软MvcMusicStore-v3.0的源代码,发现忽略了很多重要的东西,特别是数据访问那一部分. 首先Microsoft SQL Server Compact 4.0 详细的介绍和下载 ...
- Entity Framework连接Mysql数据库并生成Model和DAL层
Entity Framework (EF,ADO.NET Entity Framework)是微软官方提供的.NET平台的ORM框架.相比于LINQ TO SQL,EF框架具有很明显的优势: EF框架 ...
- 使用Entity Framework Core访问数据库(Oracle篇)
前言 哇..看看时间 真的很久很久没写博客了 将近一年了. 最近一直在忙各种家中事务和公司的新框架 终于抽出时间来更新一波了. 本篇主要讲一下关于Entity Framework Core访问ora ...
- Entity FrameWork(实体框架)是以ADO.NET Entity FrameWork ,简称为EF
Entity FrameWork(实体框架)是以ADO.NET Entity FrameWork ,简称为EF Entity FrameWork的特点 1.支持多种数据库(MSSQL.Oracle.M ...
随机推荐
- quartz使用(整合spring)
quartz与spring整合后,还是需要Scheduler实例.JobDetail实例.Trigger实例,只不过是用FactoryBean的方式创建了. 在spring-context-suppo ...
- OSG DB的插件地址设置
今天搞了一整天OSG,结果每次都说could not find plugin,就是说找不到OSG的插件去加载文件,我大概看了下OSG的插件机制,发现他是用插件的形式下去读取文件的 http://blo ...
- rockmongo配置文件config.php
使用编辑器(比如notepad或者VI/VIM命令)打开RockMongo安装目录下的config.php,所有的配置都在这里. 认证 mongo_auth 和control_auth 在开始使用Ro ...
- pat02-线性结构3. 求前缀表达式的值(25)
02-线性结构3. 求前缀表达式的值(25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 算术表达式有前缀表示法.中缀表示法和后缀表示法 ...
- pat1009. Product of Polynomials (25)
1009. Product of Polynomials (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...
- DistinctBy
如何很好的使用Linq的Distinct方法[全屏看文] Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&q ...
- net 预览文件 转换文件
预览SWF文件 swfobject.js (google浏览器 会阻止 需设置) @{ ViewBag.Title = "PdfPreview"; Layout = " ...
- J2EE课程设计:在线书店管理系统
1.系统实现 使用SpringMVC框架进行开发 使用Maven进行系统构建 使用MySql数据库 项目只实现了查看图书,搜索图书,加入购物车,创建订单,图书管理等基本功能 前台使用Bootstrap ...
- 初学Hadoop之计算TF-IDF值
1.词频 TF(term frequency)词频,就是该分词在该文档中出现的频率,算法是:(该分词在该文档出现的次数)/(该文档分词的总数),这个值越大表示这个词越重要,即权重就越大. 例如:一篇文 ...
- 关于MySQLServer5.6配置问题
配置MySQL MySQL数据库下载以后在根目录添加my.ini配置文件 需要注意的是配置文件的二个属性: basedir=D:\MySqlServer # mysql所在目录 根据需求改 MySQL ...