MVP基本了解及使用和封装

前言

想了解一个新事物我会按以下步骤来:

1、它是什么;

2、它有什么用(出现的理由),且有什么优缺点

而这里对mvp阐述分为以下步骤:

一、MVP出现原因;

二、MVP简单例子;

三、MVP总结

       1、mvp是什么;

       2、mvp有什么用?

       3、mvp有那些缺点?。

四、MVP简单封装(简化MVP使用,把公共部分抽离出来,也就是所谓的封装,类似BaseActivity那样的基类)。

另外本人水平有限,有什么疑问的地方可以提出来相互讨论。

MVP出现原因

 

Android场景举例:

 

功能需求:点击一个按钮,然后在点击监听里做一些操作(什么操作都可以,下面会具体说是什么操作)。

我们使用android studio来实现这个功能,步骤:

1、在res/layout下创建一个xml文件然后添加按钮控件;

2、在activity下设置该按钮的监听事件,然后在监听听里面做一些你想要的操作。

 

问题起因(假设1):

我们可以想象一下,如果我在上面那个按钮的点击事件里做访问网络,然后获取json数据,这个操作是不是和activity或xml(UI)联系在一起的呢?如果访问网络获取数据出现问题是不是就会牵扯到activity(UI)呢?我们再想象一下,如果我那个activity有20个类似按钮监听里的逻辑操作,都和activity牵扯在一起,会有什么后果?Bom,Bom,Bom。整个activity(UI)除了臃肿,还有就是一堆逻辑傻操作都和activity牵扯在一起,出事也牵扯到activity(UI),如果你遇到一个Activity里的业务逻辑代码就能有一万多行(没遇到和做过的兄弟可能没这体会),当你来维护和迭代功能的时候,就应该能体会到一种MMP的感受了。这里得引用一句好的应用应该是“高内聚低耦合”这句话。

 

怎么解决问题?

 

这时候mvp出现了,然后体现了它的作用和优点,mvp就是决解上面问题而出现的吧,我也没查过,不过使用mvp架构思想,就可以很好的解决开发中存在的某些问题。解决什么问题呢?后面我们就知道能解决那些问题了;但首先我们得知道mvp每一层的意思。

 

 

 

基本了解

 

这里借用这位兄弟的一段话和图(http://www.jianshu.com/p/bd99bda72912

 

MVP是Model-View-Presenter,它们的关系如下图:

 

 

 

Model:业务逻辑和实体模型,用来操作实际的数据,包含Bean和Model的抽象接口来降低耦合。
View:就是Android中的视图,需要建立一个View的抽象接口View Interface。
通过实现View的接口来实现View与Presenter的交互,从而降低耦合。
对应于Activity,负责View的绘制与用户交互;
Presenter:View和Model的中间枢纽,处理和用户交互的逻辑。
 

 

 

 

MVC就是Model-View-Controller,它们的关系如下图:

(数据模型)Model:数据的封装和保存,业务逻辑和实体模型
(视图)View:视图界面,对应于布局文件
(控制器)Controller:业务逻辑,对应于Activity、Fragment等

 

它们的逻辑为:View传送指令到Controller,Controller完成业务逻辑后,改变Model的状态,Model将新的数据发送到View,这就是MVC模式的处理逻辑。

 

MVP和MVC的对比:

 MVP架构:

      View不直接与Model交互,而是通过与Presenter交互来与Model间接交互。

      Presenter与View的交互是通过接口来进行的。

      通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。

 MVC架构:

      View可以与Model直接交互。

      Controller是基于行为的,并且可以被多个View共享。

      可以负责决定显示哪个View。

 

 

了解了mvp每一层的意思和逻辑后,我们现在就以上面按钮例子以MVP的思想架构来实现,看看有什么不同。

 

mvp每一层意思一定要搞清楚!mvp每一层意思一定要搞清楚!mvp每一层意思一定要搞清楚!

 

 

MVP简单例子

 

例子功能:一个按钮,点击该按钮实现网络请求,返回网络数据。

例子具体显示功能:

1、点击按钮就去请求网络数据;

2、显示progressbar(提示网络数据请求中);

3、请求结束,返回数据(有成功和失败,这里为了简单,只写成功);

4、隐藏progressbar(表示请求结束)。

 

下面是该例子的工程结构

 

 

 

MVP简单例子步骤

1、首先我们在res/layout下建立一个xml,在里面添加按钮和文本还有progressbar控件,这里就不贴代码了;

 

2、下面是MainActivity代码:

 

package com.mvptest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.mvptest.mvp.presenter.MainPresenter;
import com.mvptest.mvp.view.IMainView;

public class MainActivity extends AppCompatActivity implements IMainView {

    private TextView mTextView;
    private Button mButton;
    private ProgressBar mProgressBar;
    private MainPresenter mainPresenter = new MainPresenter(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initListener();
    }

    private void initView() {
        mTextView = (TextView) findViewById(R.id.tv_data);
        mButton = (Button) findViewById(R.id.bt_data);
        mProgressBar = (ProgressBar) findViewById(R.id.pb);
    }

    private void initListener() {
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //网络请求加载数据
                mainPresenter.loadData();
            }
        });
    }

    
    //======================下面是继承mvp/view包下的IMainView需要实现的方法=========================
    @Override
    public void showDialog() {
        mProgressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideDialog() {
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void showData(String data) {
        mTextView.setText(data);
        Toast.makeText(this, "请求数据成功", Toast.LENGTH_SHORT).show();
    }
}

 

 

我们看到上面的MianActivity继承mvp/view包下的IMainView,然后实现了某些方法,这些方法并没有做什么业务逻辑操作,而是只做了UI的显示。另外MainActivity里面的

private MainPresenter mainPresenter = new MainPresenter(this);和
mainPresenter.loadData()两行代码现在不需要知道里面做了什么,到这里只要知道当我们点击按钮时
调用mainPresenter.loadData()是请求网络数据操作就行,然后我们继承IMainView实现了需要重写的
方法,在重写的方法里做更新UI的操作就行了。

小结:
我们在前面就说了mvp的v,也就是view层责任就是显示IU,其他事都不会去做,那我们在这里就给mvp中的v,也就是view层给个具体一些的概念,它指什么?
它指项目中res/layout下的xml文件和activity或fragment(也就是UI了)。


3、接下来是大家之前比较关心mvpView包下IMainView接口的代码:

package com.mvptest.mvp.view; 
public interface IMainView {
void showDialog();//显示progressbar进度 
void hideDialog();//隐藏progressbar进度 
void showData(String data);//显示网络请求数据 } 

IMainView就是一个接口,里面3个方法,作用是把网络请求数据结果回掉(返回)给MainActivity(UI)更新。怎么个回掉呢,不急后面会说,现在我们只要知道这个接口有什么方法。

小结:
到这里我们可以知道mvp中的v,也就是view层指什么了,也就是和直接操作UI有关的东西,我们这里具体指MainActivity、xml布局、IMainView,但是我并没有把MainActivity放到mvp/view包下,只是为了更加清晰的说明

 

4、mvp/presenter包下MainPresenter代码:

package com.mvptest.mvp.presenter; 
import com.mvptest.mvp.model.ILoadDataListener; 
import com.mvptest.mvp.model.MainModle;
import com.mvptest.mvp.view.IMainView; 

public class MainPresenter { 

private IMainView mIMainView;
private MainModle mMainModle; 

public MainPresenter(IMainView mIMainView) {
this.mIMainView = mIMainView;
this.mMainModle = new MainModle(); 
}

/** * 加载网络数据 */ 
public void loadData() { 

     //回掉显示进度的progressbar接口
    mIMainView.showDialog(); 
    //请求数据 
    mMainModle.getData(new ILoadDataListener() {
       @Override 
       public void loadSuccess(String data) { 
          //回掉隐藏进度的progressbar接口 
           mIMainView.hideDialog();
         //回掉显示返回请求数据的接口 
           mIMainView.showData(data); } });

 } 
}

前面说完了mvp中的v,也就是view层,现在到mvp中的p,也就是presenter层了,而且前面我们也说了presenter的职责是什么,它负责view和model中间的协调,但是不互相影响。presenter也只是负责协调,其他逻辑或者显示UI都不会去做,只做自己的事情,那就是给view和model充当一座桥。

 

我们看到上面MainPresenter全是都是接口的调用(MainModle后面会说到),并没有做业务逻辑或UI处理等其他事情,因为我们一开头就说了mvp每一层都有自己 的职责,不会多做其他不属于自己的事情。

小结:

我们已经了解了mvp中view层,现在到presenter层,开头我们说了它作用就是连接view和modle的桥梁,在上面MainPresenter代码中也看到,只做链接IMainView和MainModle(各种接口回掉)的事情,这里presenter层具体指MainPresenter这个类。

5、接下来下面是mvp/modle包下MainModle代码:

我们前面说完了mvp的view层、presenter层,现在到modle层了。

前面我们也说了modle层的职责,它的职责是什么?当然是处理业务逻辑等操作咯。

package com.mvptest.mvp.model;

import android.os.Handler;

/**
 * Created by tu2460 on 2017/4/8.
 */

public class MainModle {
    private Handler mHandler = new Handler();

    public void getData(final ILoadDataListener loadDataListener){
        //在这里去获取网络数据,为了简化这里就使用handler模拟了
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //回掉请求成功的接口
              loadDataListener.loadSuccess("网络获取的数据");
            }
        },3000);
    }

}
 

MainModle里的loadDataListener.loadSuccess("网络获取的数据")是一个网络请求监听接口,案例是写在里面合理些的,但是这里也是为了看得清楚些,就把他单独写出来了,放在了mvp/modle下ILoadDataListener。

 

6、下面是mvp/model包下ILoadDataListener代码:

 

package com.mvptest.mvp.model;

/**
 * Created by tu2460 on 2017/4/8.
 */

public interface ILoadDataListener {
    void loadSuccess(String data);
}
 

ok,我们看到上面MainModle做了什么呢?做了网络请求数据的业务操作,然后把结果通过ILoadDataListener也就是网络请求监听的接口处理。

 

小结:

我们前面知道了mvp中的view层,然后知道了presenter层,现在也知道了modle层,modle层的作用就是做一些业务逻辑处理等,而这里的modle层指:

项目mvp/modle包下的MainModle和ILoadDataListener(这个接口也可以写到MainModle里,根据个人喜好,MVP只是个思想)。

MVP总结

MVP是什么鬼?

mvp是一种思想架构,一种开发模式,上面的demo就是使用了mvp这种思想完成的。

具体点:上面整个demo就是以mvp思想架构搭建的,项目mvp包下分成了3块

1、model 块;

2、presenter 块;

3、view  块;

很清楚,每一块职责也很明确,并且不相互影响,使用了大量接口降低耦合,这就是mvp,它只是一种想法,模式罢了。

 

MVP有什么用?

现在我们回到一开头就提到问题,前言里的起因:(不知道怎么设置标签让大家点击“起因:”就可以跳到上面大哭)

而我们demo以mvp模式来完成的

1、view层只负责UI更新,显示;

2、modle层只负责业务逻辑的处理;

3、presenter层,各种接口调用,协调view和modle层。

 

此刻在想想前面的前言里谈到起因里的问题,现在还会有那样的问题吗?

mvp作用是什么?清晰明确,还有呢?易于维护、扩展,还有呢?解耦,还有吗?这个还得你自己去使用...

 

MVP缺点

上面demo中我们也看到了,一个简单的点击按钮请求网络对比普通写法多了那么多类(上面是为了更加简单介绍才没写那么多的~~),没错缺点是你需要考虑的东西变多了,需要写的类也变多了,这里还得说明一下上面举得例子,上面例子是为了更加简单解释MVP,并没有很标准以MVP去实现demo的功能,如果那样去做就会多出2个接口类,看起来会更加模糊。除了类爆炸,还有吗?这你得自己去使用MVP,并且在去了解MVC、MVVM等其他思想对比后才能看得更加清楚了。

 

小总结:

从上面的每个小节我们知道了mvp,然后具体点也知道每一层指什么东西了(例如demo中),这里我们在整理下上面demo的思路:

1、我们点击按钮;

2、按钮响应网络请求事件,也就是使用presenter层mainPresenter.loadData()方法;

3、方法里面先调用显示progressbar加载进度接口,然后在调用Modle层里的方法,也就是

mMainModle.getData(ILoadDataListenerloadDataListener);

4、Modle层MainModle里的getData方法执行网络请求操作和其它业务逻辑操作完后,把成功请求到的数据通过Presenter层,也就是MainPresenter回掉给MainActivity,也就是MainActivity继承了mvp/view包下的IMainView重写的方法,数据会回掉到重写的方法里。

 

顺序是:View层响应操作->通过Presenter层通知->Modle层执行业务逻辑,然后业务逻辑处理完->通过Presenter层把数据或结果回掉给->View层用于更新UI。

MVP简单封装

我们知道BaseActivity、BaseFragment、Base...这里自然也要封装一下,这里只是对上面的demo进行封装示范,具体项目封装根据情况。

我们在原来的demo下建立一个base包用来放公用的一些东西。

1、mvp/view包下的IMainView里有showDialog()和hideDialog()方法,这两个方法大多数都会用到,我们把公共部分抽取出来,放到名字为MVPIBaseView里,代码如下:

package com.mvptest.base;

/**
 * Created by tu2460 on 2017/4/9.
 */

public interface MVPIBaseView {
    void showDialog();
    void hideDialog();
}

 

2、mvp/presenter包下的MainPresenter构造方法里每个都要绑定IMainView这样的view,我们也抽取出来,另外还有一个事情要说,就是presenter会持有view,比如网络请求,这时如果返回退出了Activity,后台异步的动作不会立即停止,这里就会有内存泄漏的隐患,所以会在presenter中加入一个销毁view的方法。

 

MVPBasePresenter代码如下:

package com.mvptest.base;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * Created by tu2460 on 2017/4/9.
 */

public class MVPBasePresenter<T> {

    protected Reference<T> mIView;//View接口类型的弱引用

    public void attachView(T iView){

        mIView=new WeakReference<T>(iView);//建立关系

    }

    protected T getView(){

        return mIView.get();
    }

    public boolean isViewAttached(){

        return mIView!=null&&mIView.get()!=null;
    }


    public void detachView(){

        if (mIView!=null){

            mIView.clear();
            mIView=null;
        }

    }

}

 

3、mvp的view层和presenter都抽取了公共部分,而modle层就这个demo来看,没有什么公用的部分就不做抽取了,但我们还得写一个MVPBaseActivity类,用于绑定和销毁mvp/view包下IMainView这样的,传递进去的上下文,因为这些步骤也是重复的。

MVPBaseActivity代码:

package com.mvptest.base;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

/**
 * Created by tu2460 on 2017/4/9.
 */

public abstract class MVPBaseActivity<V, T extends MVPBasePresenter<V>> extends AppCompatActivity {

    protected T mPresenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();//创建presenter
        mPresenter.attachView((V) this);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPresenter.detachView();
    }


    protected abstract T createPresenter();
}
 

 

4、最后我们看看我们原来的MainActivity有什么变化,代码如下:

 

package com.mvptest;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.mvptest.base.MVPBaseActivity;
import com.mvptest.mvp.presenter.MainPresenter;
import com.mvptest.mvp.view.IMainView;

public class MainActivity extends MVPBaseActivity<IMainView,MainPresenter> implements IMainView {

    private TextView mTextView;
    private Button mButton;
    private ProgressBar mProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initListener();
    }

    @Override
    protected MainPresenter createPresenter() {
        return new MainPresenter();
    }


    private void initView() {
        mTextView = (TextView) findViewById(R.id.tv_data);
        mButton = (Button) findViewById(R.id.bt_data);
        mProgressBar = (ProgressBar) findViewById(R.id.pb);
    }

    private void initListener() {
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //网络请求加载数据
                mPresenter.loadData();
            }
        });
    }


    //======================下面是继承mvp/view包下的IMainView需要实现的方法=========================
    @Override
    public void showDialog() {
        mProgressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideDialog() {
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void showData(String data) {
        mTextView.setText(data);
        Toast.makeText(this, "请求数据成功", Toast.LENGTH_SHORT).show();
    }
}
  

上面和原来比有什么变化呢? private MainPresenter mainPresenter = new MainPresenter(this);换成了在重写的createPresenter()方法里了,另外按钮点击事件里的对象使用的是MVPBaseActivity里的mPresenter了。

总结:

mvp只是开发多了的人而提出的一种开发模式,方法罢了,具体怎么用还是得看自己。下面该文章例子的MVP基本写法demo,需要的可以下载看看。当你熟练后,就可以对自己的项目以MVP思想进行属于相应项目和你的封装了。

demo下载

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
清晰完整PDF版本,是我从网上买来的 共 60MB,分为11个分卷 在 CSDN 上只有我整个是清晰完整的 LINQ 实战 1/11 LINQ 实战 .NET 2010 SQL 出版社:人民邮电出版社 ISBN:9787115208514 原价:65元 作者:(法)马格里,(美)艾歇特,(美)伍利 著,陈黎夫 译 出版日期:2009-8-1 字数:668000 页码:416 内容提要 -------------------------------------------------------------------------------- 作为.NET上连接编程语言和数据库、内存对象、XML等各种类型数据之间的桥梁,LINQ引入了一种处理数据的全新理念,将查询无缝集成至开发语言之上。本书第一部分介绍了LINQ技术及C#和VB为此提供的新语言特性,第二、三、四部分详细介绍了LINQ的三大主要功能LINQ to Objects、LINQ to SQL、LINQ to XML,第五部分研究了LINQ的可扩展性、在应用程序中使用各种LINQ功能的方法以及LINQ to DataSet。   本书适合于使用C#和VB.NET的软件开发者。 编辑推荐 -------------------------------------------------------------------------------- 微软MVP呕心沥血之作,LINQ圣经,深入全面,引人入胜,丰富实例,兼顾C#和VB.NET语言。   本书作者是LINQ社区中的重要成员,他们在书中展示了这一技术的精髓……快去享受这一盛宴吧。          ——Matt Warren,微软主架构师,LINQ之父   LINQ方面的杰作!深入、全面、客观,令人欲罢不能。强烈推荐!         ——Patrick Smacchia,微软MVP,《C#和.NET 2.0 实战》作者 目录 -------------------------------------------------------------------------------- 第一部分 从这里开始 第1章 LINQ简介 2 1.1 LINQ是什么 2 1.1.1 概览 3 1.1.2 LINQ的功能 3 1.1.3 作为语言扩展的LINQ 4 1.2 为什么需要LINQ 6 1.2.1 常见问题 6 1.2.2 解决理念上的失调 8 1.2.3 LINQ给出解决方案 12 1.3 LINQ的设计目标及起源 13 1.3.1 LINQ项目的设计目标 13 1.3.2 一点历史 14 1.4 LINQ to Objects初步:查询内存中的集合 15 1.4.1 先决条件 15 1.4.2 Hello LINQ to Objects 17 1.5 LINQ to XML初步:查询XML文档 20 1.5.1 为什么需要LINQ to XML 20 1.5.2 Hello LINQ to XML 22 1.6 LINQ to SQL初步:查询关系型数据库 26 1.6.1 LINQ to SQL功能概览 26 1.6.2 Hello LINQ to SQL 26 1.6.3 进一步了解LINQ to SQL 30 1.7 小结 30 第2章 C#和VB语言的增强特性 31 2.1 新语言的增强特性一瞥 31 2.1.1 列出当前正在运行的所有进程 32 2.1.2 将返回结果封装成类 33 2.2 隐式类型局部变量 34 2.2.1 语法 35 2.2.2 使用隐式类型局部变量改进实例程序 35 2.3 对象和集合的初始化器 37 2.3.1 引入对象初始化器的动机 37 2.3.2 集合初始化器 38 2.3.3 用对象初始化器改进实例程序 39 2.4 Lambda表达式 40 2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 2.5.4 注意事项 52 2.6 匿名类型 54 2.6.1 使用匿名类型组合数据 55 2.6.2 没有名字的类型也是类型 55 2.6.3 使用匿名类型改进实例程序 56 2.6.4 匿名类型的限制 57 2.7 小结 58 第3章 LINQ构建块 61 3.1 LINQ对.NET的扩展 61 3.1.1 语言扩展回顾 61 3.1.2 构成LINQ基础的核心元素 62 3.2 序列 63 3.2.1 IEnumerableT接口 63 3.2.2 迭代器回顾 64 3.2.3 延迟查询执行 66 3.3 查询操作符 69 3.3.1 查询操作符是什么 69 3.3.2 标准查询操作符 71 3.4 查询表达式 72 3.4.1 查询表达式是什么 72 3.4.2 编写查询表达式 73 3.4.3 标准查询操作符与查询表达式的关系 75 3.4.4 限制 76 3.5 表达式树 78 3.5.1 Lambda表达式回顾 78 3.5.2 表达式树是什么 78 3.5.3 IQueryable,另一种实现延迟查询执行的方法 81 3.6 LINQ的程序集以及命名空间 81 3.7 小结 83 第二部分 查询内存中的对象 第4章 熟悉LINQ to Objects 86 4.1 实例程序简介 86 4.1.1 程序目标 86 4.1.2 程序功能 87 4.1.3 业务逻辑实体 87 4.1.4 数据库架构 87 4.1.5 示例数据 89 4.2 用LINQ操作内存中的集合 90 4.2.1 能够查询什么 90 4.2.2 支持的操作 94 4.3 在ASP.NET和Windows Forms中使用LINQ 95 4.3.1 Web应用程序中的数据绑定 95 4.3.2 Windows Forms应用程序中的数据绑定 100 4.4 常用的标准查询操作符 103 4.4.1 约束操作符Where 104 4.4.2 投影操作符 105 4.4.3 Distinct操作符 107 4.4.4 转换操作符 108 4.4.5 聚合操作符 109 4.5 用不同的方式显示内存中的集合 110 4.5.1 排序 110 4.5.2 嵌套查询 111 4.5.3 分组 113 4.5.4 使用连接 114 4.5.5 分区 117 4.6 小结 121 第5章 超越基本的内存数据查询 122 5.1 常见使用场景 122 5.1.1 查询非泛型集合 123 5.1.2 按照多个条件分组 125 5.1.3 动态查询 127 5.1.4 LINQ to Text Files 135 5.2 设计模式 137 5.2.1 函数式创建模式 138 5.2.2 ForEach模式 140 5.3 性能分析 142 5.3.1 选择恰当的流操作方式 142 5.3.2 当心立即执行 144 5.3.3 LINQ to Objects会降低代码的性能吗 146 5.3.4 使用LINQ to Objects的代价 149 5.3.5 性能和简洁:鱼和熊掌不可兼得吗 151 5.4 小结 152 第三部分 查询关系型数据 第6章 LINQ to SQL入门 156 6.1 走入LINQ to SQL 157 6.1.1 创建对象映射 159 6.1.2 设定DataContext 161 6.2 通过LINQ to SQL读取数据 161 6.3 继续改进查询 165 6.3.1 过滤 165 6.3.2 排序和分组 167 6.3.3 聚集 168 6.3.4 连接 169 6.4 操作有层级关系的对象 171 6.5 数据加载的时机以及为何要关心这些 174 6.5.1 延迟加载 174 6.5.2 立即加载详细信息 175 6.6 更新数据 177 6.7 小结 179 第7章 揭开LINQ to SQL的本质 180 7.1 对象与关系数据的映射 180 7.1.1 通过在类中添加属性 181 7.1.2 使用外部XML文件实现映射 185 7.1.3 使用SqlMetal工具 186 7.1.4 LINQ to SQL设计器 188 7.2 将查询表达式转换为SQL 190 7.2.1 IQueryable接口 190 7.2.2 表达式树 191 7.3 业务实体的生命周期 193 7.3.1 跟踪变化 195 7.3.2 提交变化 196 7.3.3 操作离线数据 198 7.4 小结 200 第8章 LINQ to SQL高级特性 201 8.1 处理并发修改 201 8.1.1 悲观式并发 201 8.1.2 乐观式并发 202 8.1.3 处理并发异常 204 8.1.4 使用事务解决冲突 207 8.2 高级的数据库功能 208 8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分方法 223 8.3.4 使用对象继承 225 8.4 LINQ to Entities简介 229 8.5 小结 231 第四部分 操作XML 第9章 LINQ to XML入门 234 9.1 什么是XML API 234 9.2 为什么需要另外一种XML编程API 235 9.3 LINQ to XML设计原则 236 9.3.1 核心概念:函数式创建 238 9.3.2 核心概念:上下文无关的XML创建过程 238 9.3.3 核心概念:简化了的名称 239 9.4 LINQ to XML中相关类的继承体系 241 9.5 在LINQ中操作XML 243 9.5.1 加载XML 243 9.5.2 解析XML 245 9.5.3 创建XML 246 9.5.4 使用Visual Basic XML字面量创建XML 249 9.5.5 创建XML文档 251 9.5.6 向XML中添加内容 254 9.5.7 从XML中移除内容 255 9.5.8 更新XML的内容 256 9.5.9 操作属性 258 9.5.10 保存XML 258 9.6 小结 259 第10章 使用LINQ to XML查询并转换XML 260 10.1 LINQ to XML轴方法 261 10.1.1 Element 262 10.1.2 Attribute 263 10.1.3 Elements 264 10.1.4 Descendants 264 10.1.5 Ancestors 267 10.1.6 ElementsAfterSelf、NodesAfterSelf、ElementsBeforeSelf和NodesBeforeSelf方法 268 10.1.7 Visual Basic的XML轴属性 269 10.2 标准查询操作符 271 10.2.1 使用Select进行投影 273 10.2.2 使用Where实现过滤 274 10.2.3 排序和分组 275 10.3 使用XPath查询LINQ to XML对象 278 10.4 转换XML 279 10.4.1 LINQ to XML转换 279 10.4.2 使用XSLT转换LINQ to XML对象 282 10.5 小结 284 第11章 LINQ to XML常见场景 285 11.1 根据XML构建对象 285 11.1.1 目标 286 11.1.2 实现 287 11.2 根据对象创建XML 290 11.2.1 目标 290 11.2.2 实现 291 11.3 根据数据库中的数据创建XML 295 11.3.1 目标 296 11.3.2 实现 297 11.4 过滤并混合从数据库以及XML中得到的数据 301 11.4.1 目标 302 11.4.2 实现 302 11.5 读取XML并更新数据库 306 11.5.1 目标 306 11.5.2 实现 307 11.6 将文本文件转换为XML 319 11.6.1 目标 319 11.6.2 实现 320 11.7 小结 322 第五部分 LINQ无处不在 第12章 扩展LINQ 324 12.1 探寻LINQ的扩展机制 324 12.1.1 LINQ各个特性是如何实现的 325 12.1.2 自定义LINQ扩展能够实现什么 326 12.2 创建自定义查询操作符 327 12.2.1 改进标准查询操作符 327 12.2.2 辅助或领域相关的查询操作符 330 12.3 基本查询操作符的自定义实现 334 12.3.1 回顾查询翻译机制 334 12.3.2 查询表达式模式的规范 335 12.3.3 示例1:跟踪标准查询操作符的执行过程 337 12.3.4 限制:查询表达式冲突 338 12.3.5 示例2:非泛型的、领域相关的操作符 340 12.3.6 示例3:非序列的查询操作符 342 12.4 查询Web服务:LINQ to Amazon 343 12.4.1 LINQ to Amazon介绍 344 12.4.2 需求 345 12.4.3 实现 346 12.5 IQueryable和IQueryProvider:LINQ to Amazon高级版本 352 12.5.1 IQueryable和IQueryProvider接口 353 12.5.2 实现 356 12.5.3 究竟发生了什么 357 12.6 小结 358 第13章 应用程序各层中的LINQ 359 13.1 LinqBooks应用程序概览 359 13.1.1 功能 359 13.1.2 程序UI概览 360 13.1.3 数据模型 362 13.2 LINQ to SQL及数据访问层 362 13.2.1 回顾传统的三层架构 362 13.2.2 用专门的数据访问层还是LINQ to SQL 364 13.2.3 LinqBooks中对LINQ to SQL的使用 368 13.3 LINQ to XML的使用 374 13.3.1 从Amazon中导入数据 374 13.3.2 生成RSS 376 13.4 LINQ to DataSet的使用 377 13.5 使用LINQ to Objects 380 13.6 可扩展性 380 13.6.1 自定义查询操作符 380 13.6.2 创建并使用自定义LINQ提供器 381 13.7 展望未来 381 13.7.1 自定义LINQ功能 382 13.7.2 LINQ to XSD:强类型的LINQ to XML 382 13.7.3 PLINQ:支持并行计算的LINQ 383 13.7.4 LINQ to Entities,ADO.NET Entity Framework的LINQ接口 383 13.8 小结 384 第14章 使用LINQ操作DataSet 385 14.1 LINQ to DataSet概览 385 14.2 DataSet回顾 386 14.2.1 DataSet使用场景及功能 386 14.2.2 DataSet是什么 387 14.2.3 Visual Studio 2008和.NET 3.5为支持LINQ to DataSet进行的改进 389 14.3 查询弱类型DataSet 390 14.3.1 为DataSet加载数据 390 14.3.2 不使用LINQ查询DataSet 394 14.3.3 使用LINQ to DataSet查询弱类型DataSet 395 14.4 查询强类型DataSet 399 14.4.1 生成强类型的DataSet 400 14.4.2 为强类型DataSet加载数据 402 14.4.3 使用LINQ to DataSet查询强类型DataSet 404 14.5 将LINQ to DataSet查询结果绑定至UI控件 406 14.5.1 使用CopyToDataTable将LINQto DataSet查询结果复制到DataTable 406 14.5.2 使用AsDataView实现双向数据绑定 408 14.6 在LINQ to DataSet中使用查询操作符 410 14.6.1 用于DataRow的FieldT和SetFieldT操作符 410 14.6.2 集合操作符以及用DataRowComparer比较DataRow 411 14.7 小结 412 附录 标准查询操作符 414 作者介绍 -------------------------------------------------------------------------------- 马格里(Fabrice Marguerie),微软C# MVP,资深.NET软件架构师,LINQ社区专家。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值