You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NHibernate中元素的保存与查询:基于Store和Item类的技术咨询

NHibernate: Save and Query Operations for Store & Item Entities

Hey there! Let's break down how to implement save and query operations for your Store and Item entities in NHibernate. First, a quick note: we'll need to tweak your entity classes and set up mappings (since NHibernate relies on these to map C# classes to database tables properly).

Step 1: Adjust Entity Classes

Your current definitions are missing key pieces for proper association. Let's update them for clarity and relationship support:

public class Store
{
    public virtual int StoreID { get; set; }
    public virtual string Name { get; set; }
    // Renamed from ItemID to Items for readability (this is the collection of related items)
    public virtual ICollection<Item> Items { get; set; } = new List<Item>();
}

public class Item
{
    public virtual int ItemID { get; set; }
    public virtual string Name { get; set; }
    public virtual double Price { get; set; }
    public virtual int Quantity { get; set; }
    // Added navigation property back to Store (required for one-to-many relationship)
    public virtual Store Store { get; set; }
}

Step 2: Set Up NHibernate Mappings

We'll use Fluent NHibernate here (it's more concise than XML mappings). Create mapping classes for each entity:

// StoreMap.cs
public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Id(x => x.StoreID); // Maps StoreID to the primary key column
        Map(x => x.Name); // Maps Name to a database column

        // Configure one-to-many relationship with Item
        HasMany(x => x.Items)
            .Inverse() // Indicates Item owns the relationship (via its Store property)
            .Cascade.All(); // Automatically save/update/delete related Items when Store is modified
    }
}

// ItemMap.cs
public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.ItemID);
        Map(x => x.Name);
        Map(x => x.Price);
        Map(x => x.Quantity);

        // Configure many-to-one relationship back to Store
        References(x => x.Store)
            .Column("StoreID"); // Maps to the foreign key column in the Items table
    }
}

Step 3: Create SessionFactory

Initialize the NHibernate SessionFactory (do this once at app startup):

var sessionFactory = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2012 // Adjust to your database provider (e.g., SQLite, PostgreSQL)
        .ConnectionString("Your_Database_Connection_String_Here"))
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<StoreMap>()) // Load mappings from your project's assembly
    .BuildSessionFactory();

Step 4: Save Operations

Save a Single Item

using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
    var newItem = new Item
    {
        Name = "Wireless Headphones",
        Price = 199.99,
        Quantity = 25
    };

    session.Save(newItem);
    transaction.Commit(); // Always commit transactions for write operations to ensure data consistency
}

Save a Store with Associated Items

Thanks to the Cascade.All setting, saving the Store will automatically save its related Items:

using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
    var newStore = new Store
    {
        Name = "Audio Hub",
        Items = new List<Item>
        {
            new Item { Name = "Bluetooth Speaker", Price = 89.99, Quantity = 15 },
            new Item { Name = "Noise Canceling Headphones", Price = 299.99, Quantity = 10 }
        }
    };

    session.Save(newStore);
    transaction.Commit();
}

Step 5: Query Operations

We'll cover common scenarios using LINQ to NHibernate (intuitive) and HQL (SQL-like syntax).

Query a Store with Its Items (Avoid N+1 Queries)

Use Fetch to load related Items in a single query:

using (var session = sessionFactory.OpenSession())
{
    var store = session.Query<Store>()
        .Fetch(s => s.Items) // Eagerly load associated Items to prevent lazy loading issues
        .FirstOrDefault(s => s.StoreID == 1);

    if (store != null)
    {
        Console.WriteLine($"Store: {store.Name}");
        foreach (var item in store.Items)
        {
            Console.WriteLine($"Item: {item.Name} | Price: ${item.Price} | Qty: {item.Quantity}");
        }
    }
}

Query Items by Price

using (var session = sessionFactory.OpenSession())
{
    var premiumItems = session.Query<Item>()
        .Where(i => i.Price > 100)
        .OrderByDescending(i => i.Price)
        .ToList();

    foreach (var item in premiumItems)
    {
        Console.WriteLine($"Item: {item.Name} | Price: ${item.Price}");
    }
}

Query with HQL

If you prefer a SQL-style approach:

using (var session = sessionFactory.OpenSession())
{
    var hql = "FROM Item i WHERE i.Store.Name = :storeName";
    var itemsFromStore = session.CreateQuery(hql)
        .SetParameter("storeName", "Audio Hub")
        .List<Item>();

    // Process results here
}

Key Notes

  • Always use transactions for write operations (save/update/delete) to keep your data consistent.
  • Use Fetch or FetchMany to avoid N+1 query problems when accessing related entities.
  • Adjust the database provider configuration to match your actual database system (e.g., SqliteConfiguration, PostgreSQLConfiguration).

内容的提问来源于stack exchange,提问作者a.ras2002

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:44:07