1

我已经搜索并尝试了许多不同的方法来使用 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,也不想事后过滤列表,但我不确定我是否可以让它工作。

感谢您的帮助,杰夫

4

1 回答 1

1

在顽固地尝试了不同的方法之后,我终于找到了一种方法。

            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.Id == bolContainerAlias.REF.Id)
                        .Select(x => x.REF)
                    );

            return result.List();

它没有回答“无法确定成员类型来自”的问题,但它确实解决了这个问题。也许答案可以帮助某人或至少提供一个例子。

于 2013-08-05T18:45:46.363 回答