开发者

Finding the implemented Class from an Interface

I have 2 classes that implment an interface. The interface is passed into a method as a parameter, and subsequently used as the T class in the following NHibernate syntax

Session.Query<T>() 

However, as the interface is implemented by 2 classes, the SQL that gets run by Session.Query is 2 Select statements (Select .. from Boy. and Select .. from Girl).

What I need to know is how to "convert" the IChild parameter into a Class, and then use that Class to populate the Session.Query() call.

The code is below. As you can see I have a workaround, but it's not pretty and with multiple IChild classes will become a mass of duplicated code.

Thanks!

public interface IChild
{
    DateTime Date { get; }
    Parent Parent { get; set; }
}

public class Boy : IChild
{
    public virtual Parent Parent { get; set; }
    public virtual DateTime GraduationDate { get; set; }
    public virtual DateTime Date { get { return GraduationDate; } set { } }
}

public class Girl : IChild
{
    public virtual Parent Parent { get; set; }
    public virtual DateTime WeddingDate { get; set; }
    public virtual DateTime Date { get { return WeddingDate; } set { } }
}

    public bool Create(IChild entity)
    {            
        //Is there an existing child record for the key details
        IChild child = null;
        if(entity is Boy)
        {
            child = Session.Query<Boy>()
                .Where(x => x.Date == entity.Date)
                .SingleOrDefault();
        }
        else if (entity is Girl)
        {
            child = Session.Query<Girl>()
                .Where(x => x.Date == entity.Date)
                .SingleOrDefau开发者_C百科lt();
        }

    return child.Parent != null;            
    }


Use generics:

public bool Create<T>(T entity)
where t : class, IChild
{            
    //Is there an existing child record for the key details
    IChild child = null;
        child = Session.Query<T>()
            .Where(x => x.Date == entity.Date)
            .SingleOrDefault();

return child.Parent != null;            
}


the generic method expects an actual compiletime class type passed to it, not some runtime type, so unless there is a non-generic version of this method that accepts a runtime Type indication I guess you're out of luck using this approach. you could however move the creation to the child itself instead and pass the session to it, that will tear this monolithical function apart and distribute it over the children who will have knowledge of the compiletime class type to pass to the generic method.

public interface IChild 
{ 
DateTime Date { get; } 
Parent Parent { get; set; } 
IChild Create(Session session);
} 

public class Boy : IChild 
{
public virtual Parent Parent { get; set; } 
public virtual DateTime GraduationDate { get; set; } 
public virtual DateTime Date { get { return GraduationDate; } set { } } 
public virtual IChild Create(Session session) { return session.Query<Boy>().Where(x => x.Date == entity.Date).SingleOrDefault(); }
} 

public class Girl : IChild 
{ 
public virtual Parent Parent { get; set; } 
public virtual DateTime WeddingDate { get; set; } 
public virtual DateTime Date { get { return WeddingDate; } set { } } 
public virtual IChild Create(Session session) { return session.Query<Girl>().Where(x => x.Date == entity.Date).SingleOrDefault(); }
} 

public bool Create(IChild entity) 
{             
    //Is there an existing child record for the key details 
    return entity.Create(Session).Parent != null;
} 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜