我已经搜索并尝试了许多不同的方法来使用 LINQ/NHibernate 执行此操作,但没有任何工作。
我正在尝试从我的数据中获取没有 BolContainer 的 REF 字段。我不断收到此错误:“无法从 bc 确定成员类型”或取回所有 REF 字段,无论它们是否有 BolContainer。
数据库
CREATE TABLE dbo.REF (Id BIGINT PRIMARY KEY IDENTITY(1,1) NOT NULL, HL_Id BIGINT REFERENCES HL(Id) NOT NULL, ElementOrder SMALLINT NOT NULL, Element01 VARCHAR(3) NOT NULL, Element02 VARCHAR(30) NOT NULL, Element03 VARCHAR(80) NULL )
CREATE TABLE dbo.BolContainer ( Id BIGINT PRIMARY KEY IDENTITY(1,1) NOT NULL, BSN_Id BIGINT UNIQUE REFERENCES BSN(Id) NOT NULL, REF_Id BIGINT UNIQUE REFERENCES REF(Id) NOT NULL, ErrorId BIGINT REFERENCES Error(Id) NULL,拒绝 BIT NULL,完成 BIT NULL,删除 BIT NULL )
实体
public class REF : EdiEntity
{
public virtual short Order { get; set; }
public virtual string Element01 { get; set; }
public virtual string Element02 { get; set; }
public virtual string Element03 { get; set; }
public virtual HL HL { get; set; }
public virtual BolContainer BolContainer { get; set; }
}
public class BolContainer : Entity
{
public virtual bool? Rejected { get; set; }
public virtual bool? Complete { get; set; }
public virtual bool? Deleted { get; set; }
public virtual BSN BSN { get; set; }
public virtual REF REF { get; set; }
public virtual Error Error { get; set; }
public virtual void AddBSN(BSN bsn)
{
bsn.BolContainer = this;
BSN = bsn;
}
public virtual void AddREF(REF r)
{
r.BolContainer = this;
REF = r;
}
public virtual void AddError(Error error)
{
error.BolContainers.Add(this);
Error = error;
}
}
映射
public class REFMap : ClassMap<REF>
{
public REFMap()
{
Id(x => x.Id);
References(x => x.HL, "HL_Id");
Map(x => x.Order, "ElementOrder");
Map(x => x.Element01);
Map(x => x.Element02);
Map(x => x.Element03);
HasOne(x => x.BolContainer)
.Cascade.All()
.Not.LazyLoad()
.Fetch.Join();
}
}
public class BolContainerMap : ClassMap<BolContainer>
{
public BolContainerMap()
{
Id(x => x.Id);
Map(x => x.Rejected).Nullable();
Map(x => x.Complete).Nullable();
Map(x => x.Deleted).Nullable();
References(x => x.BSN, "BSN_Id")
.Cascade.All();
References(x => x.REF, "REF_Id")
.Cascade.All()
.Not.LazyLoad()
.Fetch.Join();
References(x => x.Error, "ErrorId")
.Cascade.All()
.Nullable();
}
}
这是我的功能,我进行了许多徒劳的尝试:
public IList<REF> GetUnprocessedBols()
{
ISession DbSession = SessionFactory.OpenSession();
//var x = from REF r in DbSession.Query<REF>()
// where r.Element01 == "MB" && r.BolContainer != null
// select r;
//return x.ToList<REF>();
//return DbSession.CreateCriteria<REF>()
// .Add(Restrictions.Where<REF>(r => r.Element01 == "MB"))
// //.Add(Restrictions.Where<REF>(r => r.BolContainer == null))
// .List<REF>();
//REF bolAlias = null;
//BolContainer bolContainerAlias = null;
//var result = DbSession
// .QueryOver<REF>(() => bolAlias)
// .Where(r => r.Element01 == "MB")
// .WithSubquery
// .WhereNotExists<BolContainer>(
// QueryOver.Of<BolContainer>(() => bolContainerAlias)
// .Where(() => bolAlias.BolContainer == null)
// .Select(x => x.REF)
// );
//return result.List();
//return DbSession
// .QueryOver<BolContainer>()
// .Right.JoinQueryOver(x => x.REF)
// .Where(r => r.Element01 == "MB")
// .Where(r => r.BolContainer == null)
// .Select(bc => bc.REF)
// .List<REF>();
return DbSession
.QueryOver<REF>()
.Where(r => r.Element01 == "MB")
.Left.JoinQueryOver(x => x.BolContainer)
.Where(bc => bc == null)
.List();
}
我想让最底层的一个工作,但会满足其中任何一个。
我宁愿不求助于 HQL,也不想事后过滤列表,但我不确定我是否可以让它工作。
感谢您的帮助,杰夫