Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LinqToSQl和成员访问在类型异常上不合法_Linq_Linq To Sql - Fatal编程技术网

LinqToSQl和成员访问在类型异常上不合法

LinqToSQl和成员访问在类型异常上不合法,linq,linq-to-sql,Linq,Linq To Sql,基本问题 我有一个执行以下代码的方法: IList<Gig> gigs = GetGigs().WithArtist(artistId).ToList(); 请注意,扩展函数“WithArtist”如下所示: public static IQueryable<Gig> WithArtist(this IQueryable<Gig> qry, Guid artistId) { return from gig in qry

基本问题

我有一个执行以下代码的方法:

IList<Gig> gigs = GetGigs().WithArtist(artistId).ToList();
请注意,扩展函数“WithArtist”如下所示:

    public static IQueryable<Gig> WithArtist(this IQueryable<Gig> qry, Guid artistId)
    {
        return from gig in qry
               where gig.Acts.Any(act => (null != act.Artist) && (act.Artist.ID == artistId))
               orderby gig.StartDate
               select gig;
    }
public static IQueryable with artist(此IQueryable qry,Guid artistId)
{
在qry从gig返回
其中gig.act.Any(act=>(null!=act.Artist)和&(act.Artist.ID==artistId))
订购人gig.StartDate
选择gig;
}
如果我将GetGigs()方法替换为在代码中构造gigs集合的方法(而不是通过LinqToSQL从DB中),我不会得到异常

因此,我相当确定问题出在我的LinqToSQl代码上,而不是对象结构上

但是,我不知道为什么LinqToSQl版本不工作,所以我在下面包含了所有相关的代码。任何帮助都将不胜感激

LinqToSQL代码

    public IQueryable<ListenTo.Shared.DO.Gig> GetGigs()
    {
        return from g in DBContext.Gigs
               let acts = GetActs(g.ID)
               join venue in DBContext.Venues on g.VenueID equals venue.ID
               select new ListenTo.Shared.DO.Gig
               {
                   ID = g.ID,
                   Name = g.Name,
                   Acts = new List<ListenTo.Shared.DO.Act>(acts),
                   Description  = g.Description,
                   StartDate    = g.Date,
                   EndDate      = g.EndDate,
                   IsDeleted    = g.IsDeleted,
                   Created      = g.Created,
                   TicketPrice  = g.TicketPrice,
                   Venue        =  new ListenTo.Shared.DO.Venue { 
                                    ID = venue.ID, 
                                    Name = venue.Name, 
                                    Address = venue.Address,
                                    Telephone = venue.Telephone,
                                    URL = venue.Website 
                   }

               };
    }



    IQueryable<ListenTo.Shared.DO.Act> GetActs()
    {
        return from a in DBContext.Acts

               join artist in DBContext.Artists on a.ArtistID equals artist.ID into art
               from artist in art.DefaultIfEmpty()

               select new ListenTo.Shared.DO.Act
               {
                    ID = a.ID,
                    Name = a.Name,
                    Artist = artist == null ? null : new Shared.DO.Artist
                    {
                       ID =  artist.ID,
                       Name = artist.Name
                    },
                    GigId = a.GigID

               };
    }

    IQueryable<ListenTo.Shared.DO.Act> GetActs(Guid gigId)
    {
        return GetActs().WithGigID(gigId);
    } 
public IQueryable GetGigs()
{
从DBContext.Gigs中的g返回
让acts=GetActs(g.ID)
在DBContext中加入场馆。g.VenueID上的场馆等于VICENUE.ID
选择newlistento.Shared.DO.Gig
{
ID=g.ID,
Name=g.Name,
Acts=新列表(Acts),
描述=g.描述,
StartDate=g.日期,
EndDate=g.EndDate,
IsDeleted=g.IsDeleted,
已创建=g.已创建,
TicketPrice=g.TicketPrice,
地点=新建ListenTo.Shared.DO.vention{
ID=地点ID,
Name=地点。Name,
地址=地点。地址,
电话,
URL=地点.网站
}
};
}
IQueryable GetActs()
{
从DBContext.Acts中的
加入DBContext中的艺术家。a.ArtistID上的艺术家等于艺术中的艺术家.ID
来自art.DefaultIfEmpty()中的艺术家
选择new ListenTo.Shared.DO.Act
{
ID=a.ID,
Name=a.Name,
艺人=艺人==null?null:新建Shared.DO.Artist
{
ID=artist.ID,
Name=艺术家。Name
},
吉吉德
};
}
IQueryable GetActs(Guid GIGIID)
{
使用gigId(gigId)返回GetActs();
} 
我已将Act、艺术家和Gig对象的代码包括在下面:

public class Gig : BaseDO
{

    #region Accessors

    public Venue Venue
    {
        get;
        set; 
    }

    public System.Nullable<DateTime> EndDate
    {
        get;
        set;
    }

    public DateTime StartDate
    {
        get;
        set;
    }

    public string Name
    {
        get;
        set;
    }

    public string Description
    {
        get;
        set;
    }

    public string TicketPrice
    {
        get;
        set;
    }

    /// <summary>
    /// The Act object does not exist outside the context of the Gig, therefore,
    /// the full act object is loaded here.
    /// </summary>
    public IList<Act> Acts
    {
        get;
        set;
    }

    #endregion
}

public class Act : BaseDO
{
    public Guid GigId { get; set; }
    public string Name { get; set; }
    public Artist Artist { get; set; }
}

public class Artist : BaseDO
{
    public string Name { get; set; }
    public string Profile { get; set; }
    public DateTime Formed { get; set; }
    public Style Style { get; set; }
    public Town Town { get; set; }
    public string OfficalWebsiteURL { get; set; }
    public string ProfileAddress { get; set; }
    public string Email { get; set; }
    public ImageMetaData ProfileImage { get; set; }

}

public class BaseDO: IDO
{
    #region Properties

    private Guid _id;

    #endregion

    #region IDO Members

    public Guid ID
    {
        get
        {
            return this._id;
        }
        set
        {
            this._id = value;
        }
    }




}
公共类Gig:BaseDO
{
#区域存取器
公众场地
{
得到;
设置
}
公共系统。可为空的结束日期
{
得到;
设置
}
公共日期时间起始日期
{
得到;
设置
}
公共字符串名
{
得到;
设置
}
公共字符串描述
{
得到;
设置
}
公共字符串票证
{
得到;
设置
}
/// 
///Act对象不存在于Gig的上下文之外,因此,
///此处加载完整的act对象。
/// 
公法
{
得到;
设置
}
#端区
}
公共类法案:BaseDO
{
公共Guid GigId{get;set;}
公共字符串名称{get;set;}
公共艺术家{get;set;}
}
公共级艺术家:BaseDO
{
公共字符串名称{get;set;}
公共字符串配置文件{get;set;}
公共日期时间{get;set;}
公共样式样式{get;set;}
公共城镇{get;set;}
公共字符串OfficeWebsiteURL{get;set;}
公共字符串配置文件地址{get;set;}
公共字符串电子邮件{get;set;}
公共ImageMetaData ProfileImage{get;set;}
}
公共类BaseDO:IDO
{
#区域属性
私有Guid _id;
#端区
#区域IDO成员
公共Guid ID
{
得到
{
返回此。\u id;
}
设置
{
这个。_id=值;
}
}
}

}

在您的类中,我没有看到任何东西表明LINQ to SQL是如何计算出哪个列是哪个列,等等


您是否希望在.NET中执行
WithArtist
方法,或将其转换为SQL?如果希望将其转换为SQL,则需要使用适当的LINQ to SQL属性来修饰Gig类(或者以其他方式配置数据上下文)。如果希望在代码中执行,只需将第一个参数类型从
IQueryable
更改为
IEnumerable

我认为问题在于GetGigs中的“let”语句。使用“let”意味着您将最终查询的一部分与要获取的主集合分开定义。问题是,如果“let”不是标量,则会导致嵌套查询。嵌套查询实际上并不符合sql的最大优点,因为它们的执行也是延迟的。在查询中,将嵌套查询的结果放置到要返回的主集合的投影中,然后再附加linq运算符


当这种情况发生时,嵌套查询被更深地嵌入将要执行的查询中,这会导致嵌套查询不在要执行的查询的外部投影中,因此必须合并到数据库上运行的SQL查询中。这是不可行的,因为它是嵌套在主sql查询中的投影中的嵌套查询,而sql没有“投影中的嵌套查询”这样的概念,因为您无法在sql中的投影中获取一组元素,只能获取标量

我也遇到了同样的问题,对我来说,解决这个问题的办法似乎是分离出一个返回IQueryable的内联静态方法调用,以便
public class Gig : BaseDO
{

    #region Accessors

    public Venue Venue
    {
        get;
        set; 
    }

    public System.Nullable<DateTime> EndDate
    {
        get;
        set;
    }

    public DateTime StartDate
    {
        get;
        set;
    }

    public string Name
    {
        get;
        set;
    }

    public string Description
    {
        get;
        set;
    }

    public string TicketPrice
    {
        get;
        set;
    }

    /// <summary>
    /// The Act object does not exist outside the context of the Gig, therefore,
    /// the full act object is loaded here.
    /// </summary>
    public IList<Act> Acts
    {
        get;
        set;
    }

    #endregion
}

public class Act : BaseDO
{
    public Guid GigId { get; set; }
    public string Name { get; set; }
    public Artist Artist { get; set; }
}

public class Artist : BaseDO
{
    public string Name { get; set; }
    public string Profile { get; set; }
    public DateTime Formed { get; set; }
    public Style Style { get; set; }
    public Town Town { get; set; }
    public string OfficalWebsiteURL { get; set; }
    public string ProfileAddress { get; set; }
    public string Email { get; set; }
    public ImageMetaData ProfileImage { get; set; }

}

public class BaseDO: IDO
{
    #region Properties

    private Guid _id;

    #endregion

    #region IDO Members

    public Guid ID
    {
        get
        {
            return this._id;
        }
        set
        {
            this._id = value;
        }
    }




}
public IQueryable<ListenTo.Shared.DO.Gig> GetGigs()
{
    var acts = GetActs(g.ID); // Don't worry this call is deferred

    return from g in DBContext.Gigs
           join venue in DBContext.Venues on g.VenueID equals venue.ID
           select new ListenTo.Shared.DO.Gig
           {
               ID = g.ID,
               Name = g.Name,
               Acts = new List<ListenTo.Shared.DO.Act>(acts),
               Description  = g.Description,
               StartDate    = g.Date,
               EndDate      = g.EndDate,
               IsDeleted    = g.IsDeleted,
               Created      = g.Created,
               TicketPrice  = g.TicketPrice,
               Venue        =  new ListenTo.Shared.DO.Venue { 
                                ID = venue.ID, 
                                Name = venue.Name, 
                                Address = venue.Address,
                                Telephone = venue.Telephone,
                                URL = venue.Website 
               }

           };
}