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="1">
    <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的映射文件,一刷新又变回去了。不知道该说什么了。关于返回多结果集的方法,我会在下一篇中总结。

原文地址:https://www.cnblogs.com/tjy9999/p/4664839.html