gpt4 book ai didi

Nhibernate 加入另一个表

转载 作者:行者123 更新时间:2023-12-04 02:12:16 24 4
gpt4 key购买 nike

我需要对客户执行连接。其中地址是主要地址并填充 PrimaryAddress1 和 PrimaryCity 字段。客户映射已经与地址类有很多关系,但我不想获取所有地址(性能问题)。

请帮忙..

类:

public class Customer
{
public Customer()
{
Addressess = new List<Address>();
}
public virtual int CustomerID { get; set; }
public virtual int? BranchID { get; set; }
public virtual int? CustTypeID { get; set; }
public virtual string CompanyName { get; set; }
public virtual string Prefix { get; set; }
public virtual string FirstName { get; set; }
public virtual string MiddleName { get; set; }
public virtual string LastName { get; set; }
public virtual string PrimaryAddress1 { get; set; }
public virtual string PrimaryCity { get; set; }
public virtual List<Address> Addresses { get; set; }
}


public class Address
{
public Address()
{
}
public virtual int LocationID { get; set; }
public virtual int? CustomerID { get; set; }
public virtual string LocationName { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string Address3 { get; set; }
public virtual string City { get; set; }
public virtual bool Primary { get; set; }
}

映射:

public TblCustomerMap()
{
Table("tblCustomers");
LazyLoad();
Id(x => x.CustomerID).GeneratedBy.Identity().Column("CustomerID");
Map(x => x.ProfileID).Column("ProfileID");
Map(x => x.BranchID).Column("BranchID");
Map(x => x.DateEntered).Column("DateEntered");
Map(x => x.DateTerminated).Column("DateTerminated");
Map(x => x.CustTypeID).Column("CustTypeID");
Map(x => x.CompanyName).Column("CompanyName").Not.Nullable().Length(50);
Map(x => x.Prefix).Column("Prefix").Not.Nullable().Length(50);
Map(x => x.FirstName).Column("FirstName").Not.Nullable().Length(50);
Map(x => x.MiddleName).Column("MiddleName").Not.Nullable().Length(50);
Map(x => x.LastName).Column("LastName").Not.Nullable().Length(50);
HasMany(x => x.Address).KeyColumn("CustomerID");
Map(x => x.PrimaryAddress1).Column("PrimaryAddress1") // from table tbladdress where address is primary and get data from address1 column
Map(x => x.PrimaryCity).Column("PrimaryCity") // from table tbladdress where address is primary and get data from city column
}

查询:

 var query = session
.QueryOver<Customer>(() => customer)
.JoinQueryOver(() => customer.Addresses, () => address)
.Where(() => address.Primary)
.List();

foreach (var customer1 in query)
{
customer1.PrimaryAddress1 = customer1.Addresses[0].Address1;
customer1.PrimaryCity = customer1.Addresses[0].City;
customer1.PrimaryState = customer1.Addresses[0].StateOrProvince;

}

新查询:

  var query = session.Query<Customer>()
.SelectMany(c => c.Addresses,
(c, a) => new {c, a})
.Where(cust => cust.a.Primary)
.Select(item => new CustomerView()
{
CustomerID = item.c.CustomerID,
CompanyName= item.c.CompanyName,
FirstName= item.c.FirstName,
LastName=item.c.LastName,
Address1=item.a.Address1,
Address2=item.a.Address2,
Address3= item.a.Address3,
City= item.a.City,
StateOrProvince= item.a.StateOrProvince
});
return query.ToList();

最佳答案

有(至少)两种方法可以实现这一目标。

1) 更直观和可读的是扩展数据库和调整NHibernate 映射。我们需要创建新的view viewPrimaryAddress

SELECT ***columns*** FROM [tbladdress] WHERE Primary = true

客户映射将如下所示:

Join("[viewPrimaryAddress]", 
{
m.Fetch.Join();
m.KeyColumn("CustomerID");
m.Map(t => t.PrimaryAddress1).Column("PrimaryAddress1");
m.Map(t => t.PrimaryCity).Column("PrimaryCity");
});

就是这样。会发出一条SQL语句,所以不需要加载Address集合

2) 第二种方法的概述

第二种方法将通过新类映射创建该 View ,有点复杂,但只能在应用程序端(C# 和 NHiberante)完成。

将创建新类 PrimaryAddress 并在类级别定义中包含过滤器(xml 映射示例:

<class name="PrimaryAddress" ... where="Primary = true" >

然后我们可以使用与 PrimaryAddress 的新多对一 关系来扩展 Customer。因此,获取列“PrimaryAddress1”和“PrimaryCity”的属性将通过在 WHERE 子句中过滤的 SQL 选择来完成。

扩展:

接下来的步骤应该指导您如何创建新映射,将主地址作为一对一属性1) C# 主地址:

public class PrimaryAddress
{
public virtual Customer Customer { get; set; }
public virtual string Address { get; set; }
public virtual string City { get; set; }
}

2)映射:

public TblPrimaryAddressMap()
{
Table("tbladdress");
LazyLoad();
Where("Primary = 1");
// Id as AddressId
References(x => x.Customer).Column("CustomerID");
Map(x => x.Address).Column("PrimaryAddress1")
Map(x => x.PrimaryCity).Column("PrimaryCity")
}

3) Customer 的新属性

public class Customer
{
..
public virtual PrimaryAddress PrimaryAddress { get; set; }

4) Customer 的新映射公共(public) TblCustomerMap(){ ... HasOne(x => x.PrimaryAddress)

此时,当您从 session 中获取Customer 时。您可以访问

customer.PrimaryAddress.Address
customer.PrimaryAddress.City

我主要使用 XML 映射。但是从这些行来看,概念应该很清楚......玩一些 fetch="join" 你可以加载 Customer 和它的 PrimaryAddress 在一个SQL 选择

如果您甚至需要客户属性 Customer.PrimaryAddress1,只需将 PrimaryAddress.Address 包装在 getter 中即可。

您将获得更多的好处是可以通过这个新属性 PrimaryAddress

进行过滤和排序

注意:这种方法对于缓存来说是脆弱的。原因是,虽然您将更改真实的 Address 实体,但没有内置机制来驱逐 PrimaryAddress。而且,您应该强制业务层只允许一个地址设置为 primary = true 的客户

关于Nhibernate 加入另一个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13523003/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com