如何搭建.NET Entity Framework分布式应用系统框架

 我来答
匿名用户
2016-05-29
展开全部
1. 利用EF建立数据库概念模型
新建一个解决方案EFServiceSystem,添加一个新项目,命名为EFModel,添加项目,在项目下添加一个ADO.NET Entity Data Model项,命名为EFModel.edmx,选择从数据库生成(假设我们已经建好了一个SQL Server数据库),一路点击下一步,直至完成。编译项目成功后就算完成。为什么要把数据库模型单独编译成一个dll呢,我将在后面给予解释。

2. 建立数据服务层
在解决方案下再添加一个类库项目,命名为EFService。
1) 利用外观模式,我们把客户端常用的查询和CUD操作方法简化为3个方法Query<T>,Save(T t),Delete(T t),根据针对接口编程的设计原则,定义一个CUD方法接口供客户端调用。
using System;
using System.Collections.Generic;
using System.Text;
namespace EFService
{
public interface IEntityHelper
{
List<T> Query<T>(string filter,params object[] args);
T Save<T>(T t);
int Delete<T>(T t);
}
}

2) 实现类EntityHelper的代码。主要思路是通过构造函数注入数据上下文实例名称,在配置文件取出其程序集限定名,通过反射创建实例,调用实例的相应方法实现接口。
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Reflection;
using System.Linq;
using System.Linq.Dynamic;
using System.Runtime.Remoting;

namespace EFService
{
/// <summary>
/// 为远程客户端提供实体查询和CUD操作的服务类
/// </summary>
public class EntityHelper : MarshalByRefObject, IEntityHelper
{
/// <summary>
/// 在config文件中配置的数据上下文名称
/// </summary>
string ContextName;
ServiceFactory factory = new ServiceFactory();
public EntityHelper(string contextName)
{
ContextName = contextName;
}

/// <summary>
/// 创建数据上下文实例
/// </summary>
/// <returns></returns>
public ObjectContext CreateObjectContext()
{
string typeName = System.Configuration.ConfigurationManager.AppSettings[ContextName].ToString();
return (ObjectContext)Activator.CreateInstance(Type.GetType(typeName));
}

/// <summary>
/// 查询操作
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filter">查询条件组合</param>
/// <param name="args">查询条件中的参数值</param>
/// <returns>返回实体集合</returns>
public List<T> Query<T>(string filter, params object[] args)
{
using (ObjectContext context = CreateObjectContext())
{
return (context.GetType().InvokeMember(
typeof(T).Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,null, context, null)
as IQueryable<T>).Where(filter, args).ToList();
}
}

/// <summary>
/// 保存实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t">要添加或修改的实体</param>
/// <returns>返回添加或者更新后的实体</returns>
public T Save<T>(T t)
{
EntityObject eo = t as EntityObject;
using (ObjectContext context = CreateObjectContext())
{
if (eo.EntityKey == null)
{
context.AddObject(t.GetType().Name, t);
}
else
{
object target = ontext.GetObjectByKey(eo.EntityKey); context.ApplyPropertyChanges(eo.EntityKey.EntitySetName, eo);
}
context.SaveChanges();
return t;
}
}

/// <summary>
/// 删除实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns>成功删除的实体的数量</returns>
public int Delete<T>(T t)
{
EntityObject eo = t as EntityObject;
using (ObjectContext context = CreateObjectContext())
{
if (eo != null && eo.EntityKey != null)
context.Attach(eo);
context.DeleteObject(eo);
return context.SaveChanges();
}
}
}
}

3) 最后,我们创建一个服务工厂类,暴露给客户端,负责以接口方式向客户端提供远程服务对象,数据服务层创建完毕。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Configuration;

namespace EFService
{
/// <summary>
/// 远程服务类工厂,负责创建服务对象
/// </summary>
public class ServiceFactory : MarshalByRefObject
{
/// <summary>
/// 创建远程服务对象
/// </summary>
/// <param name="connStringName">数据上下文名称</param>
/// <returns>远程服务接口</returns>
public IEntityHelper CreateEntityHelper(string contextName)
{
return new EntityHelper(contextName);
}
}
}

3. 创建运行服务的宿主程序。实际开发中,通常选择创建一个windows服务程序来运行Remoting,但是服务需要安装才能启动,运行和调试起来都比较繁琐,所以这里创建一个简单的控制台程序来运行它。在解决方案下添加一个控制台程序项目,在program.cs编写如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace EFServiceHost
{
class Program
{
static void Main(string[] args)
{
ChannelServices.RegisterChannel(new TcpChannel(9932),false);
RemotingConfiguration.ApplicationName = "EFService"; RemotingConfiguration.RegisterActivatedServiceType(typeof(EFService.ServiceFactory));
Console.WriteLine("Start Server,Press any key to exit.");
Console.ReadLine();
}
}
}

配置文件App.Config主要包括数据库连接信息以及自己定义一个数据上下文名称(这里和数据库连接名称相同,事实上不必相同),数据库连接信息可以从EFModel项目中配置文件中直接拷贝过来。内容如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="SchoolEntities"connectionString="metadata=res://*/EFModel.csdl|res://*/EFModel.ssdl|res://*/EFModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=192.168.0.110/SQLEXPRESS;Initial Catalog=School;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" >
</add>
</connectionStrings>
<appSettings >
<add key="SchoolEntities" value="EFModel.SchoolEntities, EFModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</appSettings>
</configuration>

编译成功后,拷贝EFModel和和EFService两个项目生成的dll文件至可执行文件EFServiceHost.exe同一目录下,点击运行EFServiceHost.exe。

4. 最后,我们建立一个winform客户端作为测试。在program.cs注册远程服务:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

//注册远程服务
RemotingConfiguration.RegisterActivatedClientType(
typeof(ServiceFactory), "tcp://localhost:9932/EFService");

Application.Run(new Form1());
}

添加一个窗体Form1,放入一个按钮,在按钮点击处理事件里加入下面的代码,示范客户端如何调用远程服务类实现查询和CUD操作,简单起见,我不演示数据库的数据变化了,反正,看代码,你懂的。

private void button1_Click(object sender, EventArgs e)
{
//通过远程服务工厂创建出远程服务对象,注意此处构造函数的参
注意此处参 // 数值为远程服务器上配置文件上的数据上下文名称
ServiceFactory factory = new ServiceFactory();
IEntityHelper entityHelper = factory.CreateEntityHelper("SchoolEntities");

//查询实体
List<Course> courses = entityHelper.Query<Course>("CourseID>@0",0);
Course course = courses.SingleOrDefault(p => p.CourseID == 1045);

//修改实体
course.Title = "update succeed";
entityHelper.Save(course);

//删除实体
entityHelper.Delete(course);

//新增实体
entityHelper.Save(new Course() { Title = "new course" });

}
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式