关于在会话中存储整个LINQ对象的想法?

Ric*_*tts 3 c# linq asp.net oop session

我想获得一些关于将整个对象存储到会话中的想法的反馈?例如,客户对象.一旦客户登录其控制面板,而不是每次需要从会话中存储的ID重新获取数据时,将整个客户对象存储在会话中的优缺点是什么?

因此,只要您需要引用客户对象,您就可以:

Customer c = (Customer)Session["objCustomer"];
Run Code Online (Sandbox Code Playgroud)

显然,您需要检查并具有刷新会话的功能.您需要在空会话或更新后运行此函数.

除此之外,还有其他问题我应该注意这样做吗?就编程而言,这似乎会好得多,而且对数据库的调用也要少得多.想什么?

Wik*_*hla 7

这不是一个好主意.

主要原因是ORMappers的工作方式 - 当你混合来自不同上下文的对象时,他们不喜欢它.这会发生在您建议的场景中 - 您在会话中有一个对象,由您的下一个(和以下)请求使用的不同上下文创建.Sonner或以后你会开始得到例外.

我个人更喜欢这样一种方法,其中包含客户ID(可能还有其他属性)的简单对象存储在会话中(或在表单cookie的自定义数据部分中),并在一个简单的语句中包含对客户对象的访问权限.涉及Items容器:

(生产代码在这里需要很少的检查,以防止更多):

const string CUSTOMERITEM = "customeritem";
public Customer Current
{
    get
    {
        if ( HttpContext.Current.Items[CUSTOMERITEM] == null )
        {
           int id = retrieve_the_id;

           using ( DbContext ctx = GetCurrentDbContext() ) 
           {
               HttpContext.Current.Items.Add( CUSTOMERITEM, ctx.Customers.FirstOrDefault( c => c.ID == id );
           }
        }
        return (Customer)HttpContext.Current.Items[CUSTOMERITEM];
    }
}
Run Code Online (Sandbox Code Playgroud)

Items容器仅在一个请求的时间内持续.上面的代码段确保每个请求只加载一次对象.

当然,与您的方法相比,每个请求需要额外增加一个查询.但优点是你永远不会弄乱数据库上下文.

请注意,有些业务流程不需要该Customer对象,但您可以直接传递客户的ID并在查询中使用:

 public IEnumerable<Order> CustomerOrders( int CustomerID ) 
 {
     // use the customer id directly, without first loading the customer object
 }
Run Code Online (Sandbox Code Playgroud)