C#Select子句返回系统异常,而不是相关的对象 [英] C# Select clause returns system exception instead of relevant object

查看:271
本文介绍了C#Select子句返回系统异常,而不是相关的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用SELECT子句中挑选出从数据库查询符合指定的name字段的对象如下:

 的ObjectQuery =从OBJ在链表类
,其中obj.Equals(对象名)
选择OBJ;

在我查询的结果来看,我得到:



{基地System.SystemException} = {布尔等于(System.Object的)}



在哪里我应该期待像一个制作模式



会有人请解释什么,我做错了什么?



< HR>

在讨论的方法,可以在这里看到:

  //这个功能搜索数据库的表中的名与对象名
公共静态T上读<属性相匹配的单个对象; T>(字符串对象名),其中T:IEquatable< T>
{使用(ISession的会话= NHibernateHelper.OpenSession())
{
&IQueryable的LT
; T>链表类= session.Query< T>(); //拉(查询)所有从数据库中的
诠释计数= objectList.Count表的对象(); //返回在表
的对象的数目//替代:整数计数= makeList.Count&所述; T>();

&IQueryable的LT; T>的ObjectQuery = NULL; //创建(T)的对象$ B $(B T)= foundObject默认我们的可查询列表的引用; //为我们找到的对象

的对象引用,如果(计数大于0)
{
//给我说有一个匹配名称的所有对象的对象名和它们存储在链表类
'的ObjectQuery'
的ObjectQuery =从OBJ,其中obj.Equals(对象名)
选择OBJ;

//确保的ObjectQuery'只有一个对象是

{
foundObject =(T)objectQuery.Single();
}

{
返回默认值(T);
}

//输出一些信息到控制台(屏幕输出)
Console.WriteLine(读做:+ foundObject.ToString());
}
//传给谁要求它找到对象的引用
返回foundObject;
}
}

请注意,我现在用的接口 IQuatable< T> 在我的方法描述符



我试图拉从数据库中的类的实例:

 公共类品牌:IEquatable<使> 
{
公共虚拟INT标识{搞定;组; }
公共虚拟字符串名称{;组; }
公共虚拟的IList<模型与GT;模型{搞定;组; }

公众制作()
{
//需要此公无参数的构造函数NHibernate的
}

公开制作(串makeName)
{
this.Name = makeName;
}

公共重写字符串的ToString()
{
返回名称;
}

// IEquatable<的执行情况; T>接口
公共虚拟BOOL等于(请MAKE)
{
如果(this.Id == make.Id)
{
返回真;
}
,否则
{
返回FALSE;
}
}

// IEquatable<的执行情况; T>接口
公共虚拟BOOL等于(字符串名称)
{
如果(this.Name.Equals(名))
{
返回真;
}
,否则
{
返回FALSE;
}
}
}

和接口被简单地描述如:

 公共接口IEquatable< T> 
{
布尔等于(T OBJ);
}


解决方案

IQueryable的< T> 执行你对后备数据存储查询(在这种情况下,它的SQL RDBMS)。您的SQL RDBMS没有的 IEquatable<理念; T> * ,而不能使用它的实现:查询功能必须是翻译到SQL和< 。code> obj.Equals(对象名)是不可翻译



您可以将的IQueryable< T> 的IEnumerable< T> 并做内存中的查询,但是这将是效率太低。你应该更改签名采取表达式来; Func键< TSource,布尔>> 谓词,名称检查传递给它:

 公共静态T上读< T>(表达式来; Func键< T,BOOL>>预计值){
使用(ISession的会话= NHibernateHelper.OpenSession() ){
返回session.Query< T>()的SingleOrDefault(pred的);
}
}

您现在可以使用此方法如下:

 让蛇=读<使>(X => x.Name ==蛇); 





* 此外,你的 IEquatable< T> 是不是在你所展示的方法应用于:等于(字符串)方法将有资格作为一种实现的 IEquatable<字符串方式> ,但它不是在你的制作

I am trying to use the select clause to pick out an object which matches a specified name field from a database query as follows:

objectQuery = from obj in objectList
              where obj.Equals(objectName)
              select obj;

In the results view of my query, I get:

base {System.SystemException} = {"Boolean Equals(System.Object)"}

Where I should be expecting something like a Car, Make, or Model

Would someone please explain what I am doing wrong here?


The method in question can be seen here:

// 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;
    }
}

Note that I am using the interface "IQuatable<T>" in my method descriptor.

An example of the classes I am trying to pull from the database is:

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;
        }
    }
}

And the interface is described simply as:

public interface IEquatable<T>
{
    bool Equals(T obj);
}

解决方案

IQueryable<T> executes your query against the backing data store (in this case, it's SQL RDBMS). Your SQL RDBMS has no idea of IEquatable<T>*, and cannot use its implementation: the query function must be translatable to SQL, and obj.Equals(objectName) is not translatable.

You can convert IQueryable<T> to IEnumerable<T> and do the query in memory, but that would be too inefficient. You should change the signature to take a Expression<Func<TSource, bool>> predicate, and pass the name checker to it:

public static T Read<T>(Expression<Func<T,bool>> pred) {
    using (ISession session = NHibernateHelper.OpenSession()) {
        return session.Query<T>().SingleOrdefault(pred);
    }
}

You can now use this method as follows:

Make snake = Read<Make>(x => x.Name == "snake");


* Additionally, your IEquatable<T> is not used in the method that you are showing: the Equals(string) method would qualify as an implementation of IEquatable<string>, but it is not mentioned in the list of interfaces implemented by your Make class.

这篇关于C#Select子句返回系统异常,而不是相关的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆