Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.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
C#和EF无法将相关实体添加到模型中_C#_Asp.net Mvc_Entity Framework - Fatal编程技术网

C#和EF无法将相关实体添加到模型中

C#和EF无法将相关实体添加到模型中,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我想得到一个包括标签的帖子列表 我有型号: public class BlogPostGetByUrlSlugDto { public int Id { get; set; } public string Title { get; set; } public string Category { get; set; } public string Color { get; set; } public string UrlSlug { get; set; }

我想得到一个包括标签的帖子列表

我有型号

public class BlogPostGetByUrlSlugDto
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Category { get; set; }
    public string Color { get; set; }
    public string UrlSlug { get; set; }
    public string Description { get; set; }
    public IList<BlogTagGetByPostIdDto> Tags { get; set; }
}

public class BlogTagGetByPostIdDto
{
    public string Name { get; set; }
    public string UrlSlug { get; set; }
}
我得到的
对象引用未设置为
行中对象的实例。选择(bp=>new BlogPostGetByUrlSlugDto

知道为什么吗

\u blogPostRepository.Query
存储库是:

public interface IRepository<T> where T : class
{
    T FindById(int id, bool asNoTracking = false);

    T FindSingle(Expression<Func<T, bool>> predicate = null, bool asNoTracking = false, params Expression<Func<T, object>>[] includes);

    IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, bool asNoTracking = false, params Expression<Func<T, object>>[] includes);


    /// <summary> 
    /// Add entity to the repository 
    /// </summary> 
    /// <param name="entity">The entity to add</param> 
    void Add(T entity);

    /// <summary> 
    /// Attach entity to the repository 
    /// </summary> 
    /// <param name="entity">The entity to attach</param> 
    void Attach(T entity);

    bool Exists(T entity);

    /// <summary> 
    /// Updates entity within the repository 
    /// </summary> 
    /// <param name="entity">The entity to update</param> 
    void Update(T entity, bool partial = false);


    /// <summary> 
    /// Mark entity by id to be deleted within the repository 
    /// </summary> 
    /// <param name="entity">The entity to delete</param> 
    void Delete(object id);


    /// <summary> 
    /// Mark entity to be deleted within the repository 
    /// </summary> 
    /// <param name="entity">The entity to delete</param> 
    void Delete(T entity);


    /// <summary>
    /// Get an item matching the id
    /// </summary>
    T GetById(int id);

    /// <summary>
    /// Get an item or itens matching the Expression including opcional parameters 
    /// </summary>
    IList<T> Get(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "");

    /// <summary>
    /// Get an item matching to prediate
    /// </summary>
    //T Get(Func<T, bool> predicate);


    /// <summary>
    /// Get all the itens matching to prediate
    /// </summary>
    IList<T> GetAll(Func<T, bool> predicate);


    ///// <summary>
    ///// Get all the element of this repository
    ///// </summary>
    ///// <returns>Entities list</returns>
    IList<T> GetAll();


    /// <summary>
    /// Allow to send Linq queries to the entity
    /// </summary>
    IQueryable<T> Query { get; }


    /// <summary>
    /// Saves the pending changes back into the DataContext.
    /// </summary>
    void Save();
}
公共接口i假设,其中T:class
{
T FindById(int-id,bool-asNoTracking=false);
T FindSingle(表达式谓词=null,bool asNoTracking=false,参数表达式[]包含);
IQueryable Find(表达式谓词=null,bool asNoTracking=false,参数表达式[]包含);
///  
///将实体添加到存储库
///  
///要添加的实体
无效添加(T实体);
///  
///将实体附加到存储库
///  
///要附加的实体
无效附加(T实体);
bool存在(T实体);
///  
///更新存储库中的实体
///  
///要更新的实体
无效更新(T实体,bool partial=false);
///  
///按id标记要在存储库中删除的实体
///  
///要删除的实体
作废删除(对象id);
///  
///在存储库中标记要删除的实体
///  
///要删除的实体
无效删除(T实体);
/// 
///获取与id匹配的项
/// 
T GetById(int-id);
/// 
///获取一个或多个与表达式匹配的项,包括选项参数
/// 
IList Get(表达式filter=null,Func orderBy=null,字符串includeProperties=“”);
/// 
///获取要预测的匹配项
/// 
//T Get(Func谓词);
/// 
///让所有的ITEN匹配来预测
/// 
IList GetAll(Func谓词);
///// 
/////获取此存储库的所有元素
///// 
/////实体列表
IList GetAll();
/// 
///允许向实体发送Linq查询
/// 
IQueryable查询{get;}
/// 
///将挂起的更改保存回DataContext。
/// 
作废保存();
}
查询的实现:

public class Repository<T> : IRepository<T> where T : class
{
    protected DbContext _dataContext;
    protected DbSet<T> _dbSet;

    public virtual IQueryable<T> Query
    {
        get
        {
            return _dbSet;
        }
    }
}
公共类存储库:IRepository,其中T:class
{
受保护的DbContext\u dataContext;
受保护的DbSet _DbSet;
公共虚拟可查询查询
{
得到
{
返回_dbSet;
}
}
}

要在主查询中加载实体(此过程称为),可以使用并将集合作为表达式传递

要使用实体框架的某些扩展,请记住添加以下命名空间:

using System.Data.Entity;
对于示例,请尝试以下内容:

var result = _blogPostRepository.Query
                               .Where(b => b.UrlSlug.Equals(urlSlug))
                               .Include(b => b.Tags) 
                               .Select(bp => new BlogPostGetByUrlSlugDto 
                                { 
                                    Id = bp.Id, 
                                    Title = bp.Title, 
                                    Category = bp.BlogCategory.Name, 
                                    Color = bp.BlogCategory.Color, 
                                    UrlSlug = bp.UrlSlug, 
                                    Description = bp.Description,
                                    Tags = bp.Tags.Select(t => new BlogTagGetByPostIdDto 
                                                        { 
                                                            Name = t.Name, 
                                                            UrlSlug = t.UrlSlug
                                                        })
                                })
                                .FirstOrDefault();

return result;
由于您调用
ToList
Single
FistOrDefault
方法,它将向数据库中执行查询。在您的代码中,您调用
ToList()
,它将在数据库中执行查询,并对标记执行每个查询(延迟加载)

阅读本文,了解更多关于如何引导Earger/延迟加载的信息。

您应该能够使用。包括IQueryable,但您应该添加

using System.Data.Entity;
因为这是一个IQueryable扩展方法

方法规范:


除此之外,您还应该检查blogcontrole是否可以为null,如果是这种情况,您需要在Select中处理它,否则它将为null,并在尝试访问null对象的属性时抛出错误

比如:

public BlogPostGetByUrlSlugDto GetByUrlSlug(string urlSlug)
{
    var blogPostQuery = _blogPostRepository.Query;

    return blogPostQuery
                .Where(b => b.UrlSlug.Equals(urlSlug))
                .Include(b => b.Tags)
                .Select(bp => new BlogPostGetByUrlSlugDto 
                { 
                    Id = bp.Id, 
                    Title = bp.Title, 
                    Category = bp.BlogCategory == null ? string.Empty : bp.BlogCategory.Name, 
                    Color = bp.BlogCategory == null ? string.Empty : bp.BlogCategory.Color, 
                    UrlSlug = bp.UrlSlug, 
                    Description = bp.Description,
                    Tags = bp.BlogTags.Select(t => new BlogTagGetByPostIdDto 
                                        { 
                                            Name = t.Name, 
                                            UrlSlug = t.UrlSlug
                                        })
                                        .ToList() 
                })
                .FirstOrDefault();
}

blogpostgetbyurlslaugdt中的
标记
集合更改为此(需要虚拟关键字):

如果不希望名称是唯一的,请为此类添加ID属性。
当您现在检索到
blogpostgetbyurlslaugdto
对象,并使用
Tags
属性时,它将检索与此对象相关联的标记。

您好,谢谢!您认为什么是最佳选项?使用ToList()在内存中执行还是不在数据库中执行?ToList将在数据库中执行,并且在ToList之后执行的所有操作都将在内存中执行。我认为最好尝试使用Include方法加载标记,并在调用
FirstOrDefault
(如果找不到任何寄存器,则返回null)而是调用ToList和Single.I无法访问“.Include”,因为我使用的存储库使用接口IQueryable查询{get;}对于blogPostQuery变量。@Patrick-现在你知道为什么通用存储库是个坏主意了。@ErikFunkenbusch,有什么更好的建议吗?什么类型是
blogPostQuery
?或者我应该问:在
\u blogPostRepository.Query
属性中发生了什么?如果你返回原始的EF查询,你可能不会有空的r引用异常。您好,谢谢。blogPostQuery的类型为IRepository\u blogPostRepository;其中,在我的存储库中,我拥有通过EF执行的所有操作,如Add Attach Exists Update,但不包括:(您必须从EF返回原始的
IQueryable
,否则内部查询将始终返回所有记录。您不能使用转换回SQL并减少负载的投影或谓词,也不能以生成一个SQL查询的方式组合来自多个存储库的查询。而且没有
Include
,no
AsNoTracking
。您正在将LINQ应用于对象以获得超大查询结果,因此为空对象引用(a
bp.BlogTags
)。在SQL中,这不会是一个问题。您能给我举个例子来帮助我吗?请准确显示
\u blogPostRepository中发生了什么。查询
并显示
IRepository
的定义。也许我可以通过示例来说明这里的错误。
public BlogPostGetByUrlSlugDto GetByUrlSlug(string urlSlug)
{
    var blogPostQuery = _blogPostRepository.Query;

    return blogPostQuery
                .Where(b => b.UrlSlug.Equals(urlSlug))
                .Include(b => b.Tags)
                .Select(bp => new BlogPostGetByUrlSlugDto 
                { 
                    Id = bp.Id, 
                    Title = bp.Title, 
                    Category = bp.BlogCategory == null ? string.Empty : bp.BlogCategory.Name, 
                    Color = bp.BlogCategory == null ? string.Empty : bp.BlogCategory.Color, 
                    UrlSlug = bp.UrlSlug, 
                    Description = bp.Description,
                    Tags = bp.BlogTags.Select(t => new BlogTagGetByPostIdDto 
                                        { 
                                            Name = t.Name, 
                                            UrlSlug = t.UrlSlug
                                        })
                                        .ToList() 
                })
                .FirstOrDefault();
}
public virtual ICollection<BlogTagGetByPostIdDto> Tags { get; set; }
public class BlogTagGetByPostIdDto
{
    [Key]
    public string Name { get; set; }
    public string UrlSlug { get; set; }
}