美文网首页
LLBL GenPro Learning

LLBL GenPro Learning

作者: Z_Dylan | 来源:发表于2018-09-29 10:00 被阅读0次

1.DataAccessAdapter

用于数据库的交互,填补单个实例,修改数据,调用存储过程,启动事务等。(注意DataAccessAdapter不是线程安全,每一个线程都应该有自己的实例,创建一个实例是非常快的,官网建议为每一次的查询创建一个新的实例)。

- 连接字符串

DataAccessAdapter会自动读取可用的 .config文件中的链接字符串,但是也可以提供一个链接字符串的重载。可以实现为每一次的调用适用不同的链接字符串。

- 查询超时

DataAccessAdapter.CommandTimeOut可以为每个调用设置查询超时时间,默认是30秒。

- 数据库连接控制

当需要使用多个数据库获取数据时可以使用KeepConnectionOpen属性保持数据库一直打开

- 递归保存

DataAccessAdapter支持递归保存,也是默认的保存方式。在设置一个属性关联到实体时,主外键值得同步性就已经完成。例如

myOrder.Customer = myCustomer,如果myCustomer实体不是新的,在保存之后会执行同步,因此标识列和排序列都是同步的

- 获取/删除/保存实体/列表类型/视图类型

DataAccessAdapter对于获取,删除,保存,填充列表类型和视图类型完全支持,并且还直接提供了对持久存储实体的更新、删除。

- 调用存储过程

DataAccessAdapter完全支持调用存储过程

- 事务

DataAccessAdapter支持ADO.NET事务以及基于System.Transactions的事务。如果调用的是已存在的事务,则会直接调用,否则会创建一个新的事务。

2.实体的使用

所有的实体类都派生自CommonEntityBase的中央基类,CommonEntityBase派生自EntityBase2,该类在ORMSupportClasses程序集中

创建一个新的实体实例

eg:CustomerEntity customer=new CustomerEntity()

实例化一个实体后可以将数据保存至数据库。

eg:

customer.Name="Dylan";

DataAccessAdapter adapter=new DataAccessAdapter();

adapter.SaveEntity(customer,true);

- 重新提取和不同步行为

在SaveEntity时如果传的是true表示在执行保存操作之后立即重新获取实体的数据,所以此时数据时最新的且是同步。如果传递是false,表示不同步,在从一个实体属性读取数据之前,必须从数据库中重新获取实体数据。如果在保存后不需要对实体操作,可以不需要传true;

- 序列/标识值重新获取

在SaveEntity之后会自动设置标识列的值,即使未指定重新获取实体,保存后也可以使用标识列的新值。newid()不会别视为序列字段,这些值不会被回读,所以在保存前需要提供这些值。

实例化一个已存在的实体

- 使用主键值

eg:

CustomerEntity customer = new CustomerEntity("CHOPS");

DataAccessAdapter adapter = new DataAccessAdapter();

adapter.FetchEntity(customer);

这样会获取主键为CHOPS的customer信息

-使用LINQ

 CustomerEntity customer=null;
 var adapter=new DataAccessAdapter();
 var metaData=new LinqMetaData(adapter);
 customer=metaData.Customer.FirstOrDefault(c=>c.CustomerId=="CHOPS");

-使用关联性实体

通过相关的实体去实例一个实体时,适配器是不支持自动数据加载,所有的数据都必须预先获取。
OrderEntity order = new OrderEntity(10254);
DataAccessAdapter adapter = new DataAccessAdapter(true);
adapter.FetchEntity(order);
order.Customer = adapter.FetchNewEntity<CustomerEntity>(order.GetRelationInfoCustomer());
adapter.CloseConnection();

加载CHOPS客户,订单号为10254的订单。使用先加载出订单再去加载客户实体。DataAccessAdapter实例化时传的参数new标识KeepConnectionOpen为true,所以在最后要CloseConnection。
会存在以下的关系:

  • order.CustomerID = Order.Customer.CustomerID
  • order.Customer.Orders.Contains(order)

-使用唯一约束的值

实体上可以具有唯一标识,eg:在CustomerEntity实体中定义了CompanyName上有唯一约束

  CustomerEntity customer=new CustomerEntity();
  DataAccessAdapter adapter = new DataAccessAdapter();
  customer.CompanyName = "Chop-suey Chinese";
  adapter.FetchEntityUsingUniqueConstraint(customer, customer.ConstructFilterForUCCompanyName());

- 使用Context对象

如果需要获取已存在于内存中的实体,可以使用Context对象。

 CustomerEntity customer = (CustomerEntity)myContext.Get(new CustomerEntityFactory(), "CHOPS");
 if(customer.IsNew)
 {
         //not found in context, fetch from database (assumes 'adapter' is a 
         //DataAccessAdapter instance)
         adapter.FetchEntity(customer);
 }

如果实体不存在Context对象中,则返回新的实体对象

- 多态提取

使用场景:BoradMember与CompanyCar是多对一的关系,CompanyCar是父类,FamilyCar和SportsCar为子类

 CompanyCarEntity car=adapter.FetchNewEntity<CompanyCarEntity>(myBoardMember.GetRelationInfoCompanyCar());

 FamilyCarEntity car=adapter.FetchNewEntity<FamilyCarEntity>(myBoardMemeber.GetRelationInfoCompanyCar());

修改一个对象实体

修改一个对象数据有多种方式:

  • 在内存中加载一个已存在的实体,更改一个或多个字段(不能是序列字段)并且调用DataAccessAdapter的SaveEntity()方法;
  • 创建新的实体,设置主键值(用于过滤),将IsNew属性设置为false,设置一个或多个值并调用DataAccessAdapter的SaveEntity()方法。这不会改变主键的值。
  • 通过DataAccessAdapter的UpdateEntitiesDirectly()方法指定主键为过滤器。

- 更改属性值

DataAccessAdapter的SaveEntity()方法将会知道传给它的实体是否是新的,并使用update查询更改数据库的数据,并用insert插入至数据库。update仅保存已更改的字段,没有更改的字段不执行更新

  CustomerEntity customer = new CustomerEntity("CHOPS");
  DataAccessAdapter adapter = new DataAccessAdapter();
  adapter.FetchEntity(customer);
  customer.Phone = "(605)555-4321";
  adapter.SaveEntity(customer);

先将Customer实体加载至内存中,更改一个字段在保存,因为设置了主键所以可以只改变一个字段并调用SaveEntity();

- 直接在数据库中更新实体

不需要将实体存入缓存中,相对会高效一些

  CustomerEntity customer = new CustomerEntity();
  customer.CustomerID="CHOPS";
  customer.Phone = "(605)555-4321";
  customer.IsNew=false;
  DataAccessAdapter adapter = new DataAccessAdapter();
  adapter.SaveEntity(customer);

必须设置主键,此时update只会更新单个实体,还得标注customer 的isNew是false,此时数据库才是执行update而不是insert;
如果需要保存后需要将实体加载会内存中,SaveEntity()传入true;

- 使用UpdateEntitiesDirectly()

将Product的CategoryId等于3的Discontinued字段设置为false。UpdateEntitiesDirectly() 返回受影响的行数。

  RelationPredicateBucket bucket = new RelationPredicateBucket(ProductFields.CategoryId == 3);
  ProductEntity updateValuesProduct = new ProductEntity();
  updateValuesProduct.Discontinued=true;
  DataAccessAdapter adapter = new DataAccessAdapter();
  int amountUpdated = adapter.UpdateEntitiesDirectly(updateValuesProduct, bucket);

删除实体

删除实体的几种方式:

  • 将实体加载至内存中再执行DataAccessAdapter.DeleteEntity();

  • 在内存中创建一个新的实例,设置主键值再调用DataAccessAdapter.DeleteEntity()。这种方式避免了将实体存在内存中。

  • 使用DataAccessAdapter.DeleteEntityCollection()方法删除实体集合。

  • 使用DataAccessAdapter.DeleteEntitiesDirectly()方法直接从数据库中删除实体。

    DataAccessAdapter adapter = new DataAccessAdapter();
    CustomerEntity customer = new CustomerEntity("CHOPS");
    adapter.DeleteEntity(customer);
    

删除是不会递归的,如果删除操作违反主外键约束会抛出异常。

相关文章

网友评论

      本文标题:LLBL GenPro Learning

      本文链接:https://www.haomeiwen.com/subject/zvrvoftx.html