1)什么是DataRow's RowState and RowVersion?
DataRow's RowState是数据行的状态,RowVersion是数据行的版本。
RowState and Row Version are both enum object.
The codesnap is the following detail:

DataRowState
[Flags]
public enum DataRowState


{
Added = 4,
Deleted = 8,
Detached = 1,
Modified = 0x10,
Unchanged = 2
}



RowVersion
public enum DataRowVersion


{
Current = 0x200,
Default = 0x600,
Original = 0x100,
Proposed = 0x400
}



2) 究竟RowState和RowVersion有什么关系呢?又个有什么用途呢?
RowState和RowVersion有一个对照关系(或许描述有点不恰当),
关系如下所示:
| RowState |
RowVersion |
| Added |
Current(Default) |
| Modified |
Current(Default) |
| Original |
| Unchanged |
Current(Default) |
| Original(Default) |
| Detached |
Proposed(Default) |
| Deleted |
Original (Default) |
For unchanged rowstate, default row version is also Proposed,从下面的例子中,你能看到。
从上面的表格可以看出,一个数据行有版本的控制,为什么要有这版本控制呢?
A)用于DataSet和DataTable内部实现,
B)
在用DataAdapter跟DB交互时(Call Update(DataSet)),用什么版本赋值。
当然只是在DBParameter上设置
SourceVersion

DataAdapter
public interface IDataAdapter


{
// Methods
int Fill(DataSet dataSet);
DataTable[] FillSchema(DataSet dataSet, SchemaType schemaType);
IDataParameter[] GetFillParameters();
int Update(DataSet dataSet);

// Properties

MissingMappingAction MissingMappingAction
{ get; set; }

MissingSchemaAction MissingSchemaAction
{ get; set; }

ITableMappingCollection TableMappings
{ get; }
}




DBParameter
public interface IDataParameter


{
// Properties

DbType DbType
{ get; set; }

ParameterDirection Direction
{ get; set; }

bool IsNullable
{ get; }

string ParameterName
{ get; set; }

string SourceColumn
{ get; set; }

DataRowVersion SourceVersion
{ get; set; }

object Value
{ get; set; }
}


3) 在DataTable.Select()和DataView.RowStateFilter区别,
public DataRow[] Select (
string filterExpression,
string sort,
DataViewRowState recordStates
)

Select
public Select(DataTable table, string filterExpression, string sort, DataViewRowState recordStates)


{
this.table = table;
this.IndexFields = table.ParseSortString(sort);
this.indexDesc = ConvertIndexFieldtoIndexDesc(this.IndexFields);
if ((filterExpression != null) && (filterExpression.Length > 0))

{
this.rowFilter = new DataExpression(this.table, filterExpression);
this.expression = this.rowFilter.ExpressionNode;
}
this.recordStates = recordStates;
}


public Object this [
DataColumn column,
DataRowVersion version
] { get; }
public DataViewRowState RowStateFilter { get; set; }
其实在性能方面,DataView比DataTable好,DataView use index.
还是回到这个主题上吧,
DataTable的方法会返回所有的版本的数据行,而DataView仅返回相关的版本。
请看下面的例子:

Example
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace DataRowEx


{
class Program

{
static void Main(string[] args)

{
TestRowStateAndRowVersion();
}

private static void TestRowStateAndRowVersion()

{
DataTable customerTable = new DataTable("Customers");
// Add columns
customerTable.Columns.Add("id", typeof(int));
customerTable.Columns.Add("name", typeof(string));

// Set PrimaryKey
customerTable.Columns["id"].Unique = true;

customerTable.PrimaryKey = new DataColumn[]
{ customerTable.Columns["id"] };

// Add ten rows
for (int id = 1; id <= 3; id++)

{
customerTable.Rows.Add(

new object[]
{ customerTable.Rows.Count, string.Format("customer{0}", customerTable.Rows.Count) });
}
customerTable.AcceptChanges();

// Change one row's value:
customerTable.Rows[0].BeginEdit();
customerTable.Rows[0]["name"] = "customer Modified";
// Add one row:
DataRow dataRow = customerTable.NewRow();
dataRow["id"] = customerTable.Rows.Count;
dataRow["name"] = "customer Added";
customerTable.Rows.Add(dataRow);

// Add one row:
dataRow = customerTable.NewRow();
dataRow["id"] = customerTable.Rows.Count;
dataRow["name"] = "customer proposed";

// Delete three rows.
customerTable.Rows[1].Delete();
customerTable.Rows[2].Delete();
customerTable.Rows[3].Delete();

// Use the Select method to find all rows matching the filter.
DataRow[] foundRows =
customerTable.Select(string.Empty, string.Empty,
DataViewRowState.OriginalRows);

PrintRows(foundRows, "filtered rows by originalRows");

// Create a DataView with the table.
DataView dataView = new DataView(customerTable);

// Set the RowStateFilter to display only added and modified rows.
dataView.RowStateFilter = DataViewRowState.Added
| DataViewRowState.ModifiedCurrent;

// Print those rows. Output = "Hello" "World";
PrintView(dataView, "ModifiedCurrent and Added");

// Set filter to display on originals of modified rows.
dataView.RowStateFilter = DataViewRowState.ModifiedOriginal;
PrintView(dataView, "ModifiedOriginal");


// Set the RowStateFilter to display only Added and modified rows.
dataView.RowStateFilter = DataViewRowState.Deleted;
PrintView(dataView, "Deleted");

//Set filter to display only current.
dataView.RowStateFilter = DataViewRowState.CurrentRows;
PrintView(dataView, "Current");

// Set filter to display only unchanged rows.
dataView.RowStateFilter = DataViewRowState.Unchanged;
PrintView(dataView, "Unchanged");

// Set filter to display only original rows.
dataView.RowStateFilter = DataViewRowState.OriginalRows;
PrintView(dataView, "OriginalRows");

dataView.RowStateFilter = DataViewRowState.None;
PrintView(dataView, "None");

}

private static void PrintRows(DataRow[] rows, string label)

{
Console.WriteLine("\n{0}", label);
if (rows.Length <= 0)

{
Console.WriteLine("no rows found");
return;
}

foreach (DataRow row in rows)

{
Console.WriteLine("Row State is {0};", row.RowState);
Console.WriteLine("Current Version is {0};", row.HasVersion(DataRowVersion.Current));
Console.WriteLine("Original Version is {0};", row.HasVersion(DataRowVersion.Original));
Console.WriteLine("Proposed Version is {0};", row.HasVersion(DataRowVersion.Proposed));

if (row.RowState == DataRowState.Deleted) continue;
foreach (DataColumn column in row.Table.Columns)

{
Console.Write("({0}) ", row[column,DataRowVersion.Default]);
}
Console.WriteLine();
}
}

static private void PrintView(DataView dataView, string label)

{
Console.WriteLine("\n" + label);
for (int i = 0; i < dataView.Count; i++)

{
Console.Write("Version is {0} -----", Enum.GetName(typeof(DataRowVersion),dataView[i].RowVersion));
Console.WriteLine(dataView[i]["name"]);
}
}
}
}

当直接访问删除的数据时,要用databview,否则会出错:
Deleted row information cannot be accessed through the row.
dataView[i].Row[1,DataRowVersion.Original]
dataView[i]["name"]
也不能用dataView[i].Row[1,DataRowVersion.Default],
对于Unchanged's RowState,如果Call BeginEdit(),没有call EndEdit(),
运行上面的例子,就知道答案了。
(4)在ADO.NET 2.0中,DatRow添加了几个新的方法:
SetAdded()and SetModified()