문제

I have searched and tried a number of different methods to do this with LINQ/NHibernate and couldn't get anything to work.

I am trying to get the REF fields that have no BolContainer from my data. I keep either getting this error: "Could not determine member type from bc" Or getting back all the REF fields, regardless of whether they have a BolContainer or not.

Database

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, Rejected BIT NULL, Complete BIT NULL, Deleted BIT NULL )

Entities

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;
    }
}

Mapping

    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();
    }

}

This is my function with a number of my various unfruitful attempts:

    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();
    }

I'd like to get the bottom most one working, but will settle for any of them.

I'd rather not resort to HQL, or filtering the List afterwards, but I'm not sure if I can get it working otherwise.

Thanks for the help, Jeff

도움이 되었습니까?

해결책

After stubbornly playing around with the different methods I tried I finally got one to work.

            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();

It doesn't answer the "Could not determine member type from" question, but it does fix the problem. Maybe the answer can help someone or provide an example at least.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top