MVC多表联合查询数据显示

随然做过几年.net开发,但一直没有做过MVC框架下的网站,这段时间无事,学习一下。下面的方法是我摸索过程中的一点总结,如果有更好的方法,欢迎告诉我,谢谢。

这段时间我只看了MVC和LinQ两本书,关于EF我是没看的,所以我的这个网站的数据层打算直接使用LinQ完成。今天准备开发了,才发现读数据是个问题,汗呀~~~

现在总结两种方法:

1.手写实体对象。

思路:写一个包含所有字段属性的实体类对象,使用LinQ将数据查询出后,经过一个转换器将数据转换为IList<T>类型,返回给视图显示。

1.实体类对象。

    public class IndexAtriclList
{
/// <summary>
/// 主键ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string UserName { get; set; }
}

2.读取数据。

DataClasses1DataContext context=new DataClasses1DataContext();
//方法1
var query = from a in context.GetTable<Articles>()
join m in context.GetTable<Members>()
on a.AutherID equals m.ID
orderby a.CreateTime
select new IndexAtriclList { ID = a.ID, Title = a.Title, CreateTime = a.CreateTime, UserName = m.UserName };
var list = Common.ToList<IndexAtriclList>(query);
return View(list);

上面这段代码中DataClasses1DataContext是LinQ To SQL设计器自动生成的代码,包括了DataContext对象及所有数据表映射。

Common.ToList是我写的一个转换器,下面会说到。

Articles,Members是LinQ的数据表映射,IndexAtriclList是第1步生成的实体对象。

3.转换数据

    public class Common {
public static List<T> ToList<T>(IEnumerable<T> data) {
List<T> list=new List<T>();
var propertys = System.ComponentModel.TypeDescriptor.GetProperties(typeof(T));
foreach (var item in data)
{
T t = Activator.CreateInstance<T>();
Type type = t.GetType();
foreach (System.ComponentModel.PropertyDescriptor p in propertys) {
object o=p.GetValue(item);
t.GetType().GetProperty(p.Name).SetValue(t, o, null);
}
list.Add(t);
}
return list;
}
}

这里我用到了泛型,想的是方法的复用,主要是想省事。

4.视图显示

@model IList<IndexAtriclList>

<h2>Index</h2>
<table border="">
<thead>
<tr>
<td>标题</td>
<td>发布日期</td>
</tr>
</thead>
@{ foreach (var item in Model)
{
<tr>
<td>@item.Title</td>
<td>@item.CreateTime</td>
</tr>
}
}
</table>

ok,到这里第一种方法完成。但是我还没想明白,如果这么做的话,手写及维护实例类就是一项艰巨的工作,不知是我的思路不对,还是有更好的方法,希望大家指正。

2.存储过程

思路:在sql server中写一个返回结果集的存储过程,LinQ直接调用即可。(这个方法真是太方便了,两分钟搞写)

1.在Sql Server中写存储过程

Create proc IndexArticleList
as
select a.ID,Title,a.CreateTime,m.UserName from Articles a
inner join Members m on a.AutherID=m.ID
go

2.调用存储过程

DataClasses1DataContext context = new DataClasses1DataContext();
//方法2
var list = context.IndexArticleList().ToList();
return View(list);

3.视图显示,方法同第1种方法。

这个方法不用我们维护实体类,LinQ会根据存储过程自动生成对应的类。我们可以在LinQ的designer.cs上看到生成的对象。

public partial class IndexArticleListResult
{ private int _ID; private string _Title; private System.DateTime _CreateTime; private string _UserName; public IndexArticleListResult()
{
} [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ID", DbType="Int NOT NULL")]
public int ID
{
get
{
return this._ID;
}
set
{
if ((this._ID != value))
{
this._ID = value;
}
}
}
......................

如果有一个复杂的查询逻辑,我们可以写在存储过程中,提升性能。

我在测试当中,发现LinQ对返回多结果集的存储过程支持并不好,每次辛辛苦苦改了LinQ的映射文件,一刷新又变回去了。不知道该说什么了。关于返回多结果集的方法,我会在下一篇中总结。

上一篇:SQLServer连接查询之Cross Apply和Outer Apply的区别及用法


下一篇:SQL Server连接查询之Cross Apply和Outer Apply的区别及用法(转载)