ICollection中的元素数量在多对多关系中为零

时间:2013-07-16 22:22:56

标签: c# entity-framework

我有一个使用Entity Framework制作的数据库。我有两个表用户和广告,它们之间的关系是多对多。除非我想在类Users中返回ICollection的数量,否则一切正常。

[Table("Advertisments")]
public class Advertisment
{
    public Advertisment()
    {
        Users = new HashSet<User>();
    }

    [Key]
    public int AdvertismentID { get; set; }

    public string Address { get; set; }

    public string City { get; set; }

    public double Rating { get; set; }

    public int NumberOfRates { get; set; }

    public string Title { get; set; }

    public string PhoneNumber { get; set; }

    public string Email { get; set; }

    public double Latitude { get; set; }

    public double Longitude { get; set; }

    public ICollection<User> Users { get; set; }

}
[Table("Users")]
public class User
{
    public User()
    {
        FavouriteAdvertisments = new HashSet<Advertisment>();
    }

    [Key]
    public int UserID { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }

    public ICollection<Advertisment> FavouriteAdvertisments { get; set; }

}

public class GetHiredDBContext : DbContext
{
    public GetHiredDBContext()
        : base("GetHiredDBContext")
    { }

    public DbSet<User> Users { get; set; }
    public DbSet<Advertisment> Advertisments { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<User>().HasMany(a => a.FavouriteAdvertisments).WithMany(u => u.Users).Map(m =>
            {
                m.MapLeftKey("UserID");
                m.MapRightKey("AdvertismentID");
                m.ToTable("UserAdvertisment");
            });
    }
}

这就是我想要做的事情:

public ICollection<Advertisment> favouriteAdvertismentsByUser(int UserID)
    {
        GetHiredDBContext db = new GetHiredDBContext();
        foreach (User user in db.Users)
        {
            if (user.UserID == UserID)
            {
                return user.FavouriteAdvertisments;
            }
        }
        return null;
    }

每次调用此方法时,ICollection中每个用户的元素数量为0!

3 个答案:

答案 0 :(得分:1)

public ICollection<Advertisment> favouriteAdvertismentsByUser(int UserID)
{
    GetHiredDBContext db = new GetHiredDBContext();

    // First of all, you probably forgot to "include" FavouriteAdvertisments
    var users = db.Users.Include(u => u.FavouriteAdvertisments);

    // Second of all, use linq!
    return users.SingleOrDefault(u => u.UserID == UserID).FavouriteAdvertisments;
}

答案 1 :(得分:0)

如果您使用Entity Framework,则需要在Linq中编写查询,以便查询提供程序可以将其转换为SQL语句。正如你现在所做的那样,它正在进行表扫描。相反,试试这个:

public ICollection<Advertisment> favouriteAdvertismentsByUser(int UserID)
{
    return new GetHiredDbContext()
        .Users
        .Single(u => u.UserID = UserID)
        .FavouriteAdvertisements;
}

有一点需要注意,此方法现在预计表中只有1条记录UserID。如果它不存在,它将抛出异常。我个人更喜欢这个,因为如果我正在调用一个方法,我希望它能够工作,异常意味着我编写了错误的代码,允许我更早地发现错误。在获得计数之前,您也不必检查您的集合是否为空。

答案 2 :(得分:0)

您的网站目前的设置方式,您必须使用EagerExplicit加载,您的相关网址不会自动加载。

要明确加载,我相信您可以使用原始查询(前提是您传递了可在DBSet中找到的实体,并进行显式调用以加载相关信息(使用Load ):

E.g。 (如果您的实体可以找到)。

public ICollection<Advertisment> favouriteAdvertismentsByUser(User userEntity)
{
    // Load the blog related to a given post
    GetHiredDBContext db = new GetHiredDBContext();

    db.Entry(userEntity).Reference(p => p.FavouriteAdvertisments).Load();

    return user.FavouriteAdvertisments;
}

虽然从你的上下文中获取你的实体可能更干净,并且在那上面调用load,而不是整理你的整个集合。

要急切加载,请在查询时使用Include发出加载请求:

public ICollection<Advertisment> favouriteAdvertismentsByUser(int userID)
{
    GetHiredDBContext db = new GetHiredDBContext();

    User myUser = db.Users
                    .Where(x => x.UserID = userID)
                    .Include(x => x.FavouriteAdvertisments)
                    .FirstOrDefault();

    return myUser.FavouriteAdvertisments;
}

要以第三种方式获取数据,使用Lazy-Loading,您必须对类进行一些更改,即将ICollection导航属性标记为虚拟,因此实体框架能够创建有效您的类的代理类型。您的数据将根据需要提供,并按需加载。

希望我没有完全错误地解决问题,即将关闭/睡觉。

祝你好运。

更多信息:http://msdn.microsoft.com/en-us/data/jj574232.aspx