【问题标题】:IList<Item> Collection Class accessing databaseIList<Item> 集合类访问数据库
【发布时间】:2010-03-23 14:19:38
【问题描述】:

我有一个包含用户的数据库。 用户拥有物品。

这些项目可以主动更改。 您如何访问集合类型格式的项目? 对于用户,我在实例化时填写所有用户属性。 如果我在实例化时加载用户的项目,并且项目发生了变化, 他们会有旧数据。

我在想,也许我需要一个 ItemCollection 类,并在用户类之外拥有一个字段/属性,这样可以遍历所有用户的项目,我可以使用 foreach 循环。

所以,我的问题是,使用某种集合从数据库访问项目的最佳实践/最佳方式是什么?在访问特定的Item时,它需要获取最新的数据库信息,并且当用户执行foreach循环时,最新的item信息必须是可用的。

即我正在尝试做的事情

Console.WriteLine(User.Items[3].ID); returns 5.
//this updates the item information and saves it to the database.
User.Items[3].ID = 13; 

//Add a new item to the database.
User.Items.Add(new Item { id = 17});

foreach (Item item in User.Items) {
    //this would traverse all items in the database.
    //not some cached copy at the time of instantiation of the user.
}

编辑:对不起,我写的这个问题有点错误。 我目前正在使用 Linq,但我有类映射到业务对象。 当我对业务对象进行遍历时,我希望它转到 Linq 数据上下文并获取信息。

当我实现一个实现接口 IList 的新类“ItemCollection”时, 我需要怎么做才能让它返回项目?

使用 User.Items[3],在 public Item 的 this[int index] 方法中实现。 index方法是否应该使用linq.Skip操作符来获取数据库中item的索引?

我只是对将业务对象集合映射到数据库感到有些困惑。

【问题讨论】:

  • 你在使用实体框架吗?
  • 不,但我使用的是 Linq to SQL

标签: c# database caching collections class-design


【解决方案1】:

虽然这是可能的,但它需要一些不寻常的要求。

首先,这会在您的数据库和应用程序之间产生过多的流量。其次,在并发环境中,这会引入大量的竞态条件。

只是一个简单的例子,代码段:

User.Items[3].ID = 13; 
User.Items[3].Color = Color.Blue; 

可能会产生不允许的状态,但是由于急于持久化状态,它在数据库中至少存在片刻。此外,上述代码段将访问数据库两次以进行简单更新。而且要保证这种变化是原子的要困难得多。

【讨论】:

  • +1 - 确切地说,通常您只需在迭代之前重新加载用户及其项目。
【解决方案2】:

您是否检查过 LINQ to SQL 或实体框架?

它们都提供了您需要的类似功能:

// Get first user with Id of 5
var users = _dbContext.Users.FirstOrDefault(u => u.Id == 5);

// Loop through all users in the context
foreach(var user in _dbContext.Users)
{
    foreach(var item in user.Items)
    {
        // Work with your item here.
    }
}

您只需要确保管理您的上下文,以便获得最新信息。

【讨论】:

    【解决方案3】:

    您需要在您的数据库类中实现 IList,并在属性更改时写入数据库。

    在某些情况下,拥有对数据的 IList 访问权限可能很好,但是当有人更改某个属性时自动写入数据库会在有人更改实例上的 20 个属性时造成不愉快的情况。

    当谈到以类似集合的方式访问数据的最佳方式时,请查看 LiNQ。

    【讨论】:

      【解决方案4】:

      您想要一个Object-Relational Mapping 工具。

      我使用并会推荐ADO.Net Entity Framework

      大多数 ORM 都包含一个缓存层。这就是你开始写的内容。

      一个很大的好处是您现在设计的缓存层是为您构建的,并且很可能会优于您(或我)的实现。

      特别是对于实体框架,发挥作用的主要组件是“Object Services”组件


      (来源:wikimedia.org

      来自“Saving Changes and Managing Concurrency”...

      对象服务跟踪更改 已对对象中的 缓存。当 SaveChanges 方法是 调用,对象服务尝试合并 更改回数据源。 SaveChanges 可能会失败并显示 OptimisticConcurrencyException 时 对象缓存中的数据更改 与所做的更改冲突 在对象之后的数据源中 添加到缓存中或在缓存中刷新。

      所以这主要是在幕后为你处理的。随着实体集的增长,您不必修改对象缓存层,因为这一切都已为您完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-16
        • 1970-01-01
        • 1970-01-01
        • 2022-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-24
        相关资源
        最近更新 更多