使用EntityFramework从连接返回一个新对象

时间:2017-05-31 13:11:45

标签: c# mysql entity-framework linq linqpad

我有点卡在这里。 我有一个数据库,其中包含项目和这些项目版本的表格:

public class Project
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string Type { get; set; }

    public List<ProjectVersion> Versions { get; set; } = new List<ProjectVersion>();

    public Project() { }
}

public class ProjectVersion
{
    public int Id { get; set; }

    public string Version { get; set; }
    public string Checksum { get; set; }
    public string Description { get; set; }

    public ICollection<EntryPoint> EntryPoints { get; set; } = new List<EntryPoint>();      
    public ICollection<System> Systems { get; set; } = new List<System>();

    public ProjectVersion() { }
}

现在我想获得一个项目的特定版本和一些详细信息

public static Project GetVersionByProjectId( int projectId, string version )
{
    using ( var ctx = new DatabaseContext() )
    {
        var query = 
            ctx.Projects
                .Where(p => p.Id.Equals(projectId))
                .Join(
                    ctx.Versions.Where( v => v.Version.Equals( version )),
                    p       => p.Id,
                    v       => v.ProjectId,
                    (p, v)  => new Project
                    {
                        Name     = p.Name,
                        Type     = p.Type,
                        Id       = p.Id,                                
                        Versions = new List<ProjectVersion>
                        {
                            new ProjectVersion
                            {
                                Checksum    = v.Checksum,
                                Description = v.Description,
                                Version     = v.Version ,
                                EntryPoints = new List<EntryPoint>(v.EntryPoints),
                                Systems     = new List<System>(v.Systems)                           
                            }
                        }
                    }
                )
                .Select(x => x);

                var result = query.ToList();

                return result[0];
            }
        }

如果我删除整个

Versions = new List<ProjectVersion>

它有效,我得到的是Project而不是Version。当我在LINQPad中尝试LINQ时出现以下错误:

Cannot create a query result of type 'System.Collections.Generic.List`1[UserQuery+ProjectVersion]'.

如何获得具有所请求版本的项目?

更新

感谢@RomanoZumbé和@Maritim的想法,我可以解决它。问题是不同类型的模型。

using ( var ctx = new DatabaseContext() )
{
    var query = 
            ctx.Projects
                .Include(p => p.Versions)
                .Where(p => p.Id.Equals(projectId))
                .Select( p =>
                    new Project()
                    {
                        Id       = p.Id,
                        Name     = p.Name,
                        Type     = p.Type,
                        Versions = 
                            p.Versions
                                .Where( v => v.Version.Equals(version))
                                .Select( v =>
                                    new ProjectVersion()
                                    {
                                        Checksum    = v.Checksum,
                                        Description = v.Description,
                                        EntryPoints = 
                                            v.EntryPoints
                                                .Select( e => new EntryPoint()
                                                {           
                                                    Call = e.Call,                                                                                          
                                                    Step = e.Step                                                                                       
                                                })                                                                                  
                                                .ToList()   
                                    })
                                    .ToList()
                    })
                    .Select(x => x);

                var result = query.ToList();

                return result[0];
}

2 个答案:

答案 0 :(得分:0)

我不知道我是否理解正确,这是我的首要考虑,但我认为如果使用Include(...)语句会更容易。因为您已经包含了该项目&#39; Versions&#39; (相当于数据库中的JOIN语句),您可以执行以下操作:

var query = 
        ctx.Projects
            .Include(p => p.Versions)
            .Where(p => p.Id.Equals(projectId))
            .Select(
                new Project
                {
                    Name     = p.Name,
                    Type     = p.Type,
                    Id       = p.Id,                                
                    Versions = p.Versions.Where(v => v.Version.Equals(version))
                });

return query.FirstOrDefault();

答案 1 :(得分:0)

我不完全确定这是你想要达到的目标,但也许它会有所帮助。

            var res = (from p in ctx.Projects
                       let v = ctx.Versions.FirstOrDefault(x => p.Versions.Any(v => v.Id == x.Id))
                       where p.Id == projectId
                    select new Project
                    {
                        Name = p.Name,
                        Type = p.Type,
                        Id = p.Id,
                        Versions = new List<ProjectVersion>()
                        {
                            new ProjectVersion
                            {
                                Checksum    = v.Checksum,
                                Description = v.Description,
                                Version     = v.Version ,
                                EntryPoints = new List<EntryPoint>(v.EntryPoints),
                                Systems     = new List<System>(v.Systems)
                            }
                        }
                    });

            return res.FirstOrDefault()