1

Entity Framework で作成したデータベースがあります。ユーザーと広告の 2 つのテーブルがあり、それらの間の関係は多対多です。クラス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 です!

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

Entity Framework を使用している場合は、Linq でクエリを記述して、クエリ プロバイダーがそれを SQL ステートメントに変換できるようにする必要があります。あなたが今持っているように、テーブルスキャンを行っています。代わりにこれを試してください:

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

注意すべきことの 1 つは、このメソッドでは、テーブル内にUserID. 存在しない場合は例外がスローされます。個人的には、メソッドを呼び出している場合、それが機能することを期待しているため、これを好みます。例外は、何か間違ったコードを記述したことを意味し、バグを早期に発見できるようにするためです。カウントを取得する前に、コレクションが null かどうかを確認する必要もありません。

于 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 を呼び出す方がおそらくクリーンですが。

Eagerly ロードするには、次を使用して、クエリ時にロード リクエストを行います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;
}

を使用して 3 番目の方法でデータを取得するにはLazy-Loading、クラスにいくつかの変更を加える必要があります。つまり、ICollectionナビゲーション プロパティを仮想としてマークし、エンティティ フレームワークがクラ​​スの有効なプロキシ タイプを作成できるようにします。データは必要に応じて利用でき、オンデマンドでロードされます。

シャットダウン/スリープしようとしているだけで、問題が完全に間違っていないことを願っています。

幸運を。

詳細: http://msdn.microsoft.com/en-us/data/jj574232.aspx

于 2013-07-16T23:28:22.440 に答える