我试图使用select子句从数据库查询中选择与指定名称字段匹配的对象,如下所示:
objectQuery = from obj in objectList where obj.Equals(objectName) select obj;
在查询的结果视图中,我得到:
base {System.SystemException} = {"Boolean Equals(System.Object)"}
我应该期待的地方Car,例如Make,或Model
Car
Make
Model
有人可以在这里解释我做错了吗?
有问题的方法可以在这里看到:
// this function searches the database's table for a single object that matches the 'Name' property with 'objectName' public static T Read<T>(string objectName) where T : IEquatable<T> { using (ISession session = NHibernateHelper.OpenSession()) { IQueryable<T> objectList = session.Query<T>(); // pull (query) all the objects from the table in the database int count = objectList.Count(); // return the number of objects in the table // alternative: int count = makeList.Count<T>(); IQueryable<T> objectQuery = null; // create a reference for our queryable list of objects T foundObject = default(T); // create an object reference for our found object if (count > 0) { // give me all objects that have a name that matches 'objectName' and store them in 'objectQuery' objectQuery = from obj in objectList where obj.Equals(objectName) select obj; // make sure that 'objectQuery' has only one object in it try { foundObject = (T)objectQuery.Single(); } catch { return default(T); } // output some information to the console (output screen) Console.WriteLine("Read Make: " + foundObject.ToString()); } // pass the reference of the found object on to whoever asked for it return foundObject; } }
请注意,我IQuatable<T>在方法描述符中使用接口“ ”。
IQuatable<T>
我尝试从数据库中提取的类的示例是:
public class Make: IEquatable<Make> { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual IList<Model> Models { get; set; } public Make() { // this public no-argument constructor is required for NHibernate } public Make(string makeName) { this.Name = makeName; } public override string ToString() { return Name; } // Implementation of IEquatable<T> interface public virtual bool Equals(Make make) { if (this.Id == make.Id) { return true; } else { return false; } } // Implementation of IEquatable<T> interface public virtual bool Equals(String name) { if (this.Name.Equals(name)) { return true; } else { return false; } } }
该接口被简单描述为:
public interface IEquatable<T> { bool Equals(T obj); }
IQueryable<T>对后备数据存储区执行查询(在本例中为SQL RDBMS)。您的SQL RDBMS不了解IEquatable<T>*,并且不能使用其实现:查询函数必须可翻译为SQL,并且obj.Equals(objectName)不可翻译。
IQueryable<T>
IEquatable<T>
obj.Equals(objectName)
您可以转换IQueryable<T>为IEnumerable<T>并在内存中执行查询,但是这样效率太低。您应该将签名更改为Expression<Func<TSource, bool>>谓词,然后将名称检查器传递给它:
IEnumerable<T>
Expression<Func<TSource, bool>>
public static T Read<T>(Expression<Func<T,bool>> pred) { using (ISession session = NHibernateHelper.OpenSession()) { return session.Query<T>().SingleOrdefault(pred); } }
现在,您可以按以下方式使用此方法:
Make snake = Read<Make>(x => x.Name == "snake");
*另外,IEquatable<T>在显示的方法中未使用your :该Equals(string)方法可以作为的实现IEquatable<string>,但在您的Make类实现的接口列表中未提及。
Equals(string)
IEquatable<string>