我有一个使用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!
答案 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)
您的网站目前的设置方式,您必须使用Eager
或Explicit
加载,您的相关网址不会自动加载。
要明确加载,我相信您可以使用原始查询(前提是您传递了可在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
导航属性标记为虚拟,因此实体框架能够创建有效您的类的代理类型。您的数据将根据需要提供,并按需加载。
希望我没有完全错误地解决问题,即将关闭/睡觉。
祝你好运。