1

更新: を使用すべきではないことを理解したDbSetので、Erenga の提案に従って実装を ICollection に変更しました

次のクラスを検討してください。

[Table("Tenant")]
public class Tenant : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Key]
    public string Guid { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

[Table("User")]
public class User : IEntity
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string Password { get; set; }
}

最初のテストでは、新しいテナントと新しいユーザーを作成し、それらを適切なテーブルに格納します。

    [Test]
    public void CreateNewUserForNewTenant()
    {
        var user = _applicationContext.Users.Create();
        user.Name = "barney";
        user.EmailAddress = "barney@flinstone.com";

        var tenant = _applicationContext.Tenants.Create();
        tenant.Name = "localhost";
        tenant.Guid = Guid.NewGuid().ToString();

        tenant.Users.Add(user); // NullReferenceException, I expected the EF would LazyLoad the reference to Users?!
        _tenantRepository.Add(tenant);
        _applicationContext.SaveChanges();
    }

NullReferenceExceptionプロパティ Users が初期化されていないため、このテストは失敗します。

EF で提供される LazyLoading に依存できるコードをどのように変更すればよいですか?

4

3 に答える 3

2
    var tenant = new Tenant
        {
            Name = "localhost",
            Guid = Guid.NewGuid().ToString(),
            Users = new List<User> { user }
        };
于 2013-01-27T13:20:03.217 に答える
2

ここには2つの問題があります。

  1. @SimonWhitehead が述べたように、参照型はデフォルトで null として初期化されます。遅延読み込みは、EF によって作成されたエンティティに対してのみ機能します。これらは実際には、遅延ロードへの追加ロジックを含むクラスのサブクラスです。

  2. DbSetエンティティでサポートされているコレクション タイプではありません。ICollectionタイプを、ISet、またはに変更する必要がありますIList

これが実際の例です

[Table("Tenant")]
public class Tenant : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Key]
    public string Guid { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

[Table("User")]
public class User : IEntity
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string Password { get; set; }
}

[Test]
public void CreateNewUserForNewTenant()
{
    var user = _applicationContext.Users.Create();
    user.Name = "barney"; 
    user.EmailAddress = "barney@flinstone.com";

    var tenant = _applicationContext.Tenents.Create();
    tenant.Name = "localhost";
    tenant.Guid = Guid.NewGuid().ToString();

    tenant.Users = new List<User> { user };
    _tenantRepository.Add(tenant);
    _applicationContext.SaveChanges();
}
于 2013-01-27T13:41:23.597 に答える
0

私はあなたがこのようなものを期待していたと思います(スレッドセーフではありません):

[Table("Tenant")]
public class Tenant : IEntity
{
    private DbSet<User> _users;

    public int Id { get; set; }
    public string Name { get; set; }
    [Key]
    public string Guid { get; set; }

    public virtual ICollection<User> Users 
    {
        get 
        {
            if (_users == null)
                _users = new List<Users>();

            return _users;
        }
        set { _users = value; }
    }
}

クラスも何らかの形で利用できると確信してLazy<T>いますが、私はそのクラスに慣れていません。

于 2013-01-27T13:34:16.077 に答える