1

我有一个用实体框架制作的数据库。我有两个表用户和广告,它们之间的关系是多对多的。一切正常,除非我想在用户类中返回 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!

4

3 回答 3

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;
}
于 2013-07-16T23:44:36.483 回答
0

如果您使用实体框架,您需要在 Linq 中编写查询,以便查询提供程序可以将其转换为 SQL 语句。正如您现在拥有的那样,它正在执行表扫描。而是试试这个:

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

需要注意的一点是,此方法现在期望您的表中恰好有 1 条记录UserID。如果不存在会抛出异常。就我个人而言,我更喜欢这个,因为如果我调用一个方法,我希望它能够工作,而异常意味着我编写了错误的代码,让我可以更早地找到错误。您也不必在获得计数之前检查您的集合是否为空。

于 2013-07-16T22:39:37.347 回答
0

您的实体当前设置的方式,您将不得不使用EagerExplicit加载,您的相关实体将不会自动加载。

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

例如(前提是可以找到您的实体)。

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

于 2013-07-16T23:28:22.440 回答