Explicit construction of entity type ‘###’ in query is not allowed

Estava eu programando, feliz da vida, quando percebi subitamente que felicidade e programação não se misturam muito bem. Surge então esta mensagem de erro:

A construção explícita do tipo de entidade ‘###’ na consulta não é permitida.

ou, em bom inglês Google friendly:

Explicit construction of entity type ‘###’ in query is not allowed

O código que gerou a mensagem pouco agradável foi este:

var res =
    from m in MyDataContext.INSCRICAOs
    group m by m.PESSOA into p
    select new MAILING()
    {
        idMailingTexto = idMailingTexto,
        nomPessoa = p.First().PESSOA.nomPessoa,
        eMail = p.First().PESSOA.eMail,
        flaEnviado = false,
    };

Minha intenção é de, a partir de dados extraídos da tabela INSCRICAO, criar entradas na tabela MAILING, usando o Linq To SQL (sem sermões sobre formas normais em banco de dados, por favor). Mas o Linq não deixa eu criar estes objetos MAILING, não a partir de uma consulta do próprio Linq.

O problema, que descobri ser um feature (como se traduz isto para o português?) parece ser antigo, e a resposta é esta:

This check was added because it was supposed to be there from the beginning and was missing.  Constructing entity instances manually as a projection pollutes the cache with potentially malformed objects, leading to confused programmers and lots of bug reports for us. In addition, it is ambiguous whether projected entities should be in the cache or changed tracked at all. The usage pattern for entities is that they are created outside of queries and inserted into tables via the DataContext and then later retrieved via queries, never created by queries.

Para mim isto é nivelar por baixo, mas enfim. O jeito foi criar um objeto idêntico ao existente, que chamei de MAILINGCLONE:

public class MAILINGCLONE
{
    public int idMailingTexto { get; set; }
    public string nomPessoa { get; set; }
    public string eMail { get; set; }
    public bool flaEnviado { get; set; }
    public DateTime datAtualiza { get; set; }
}

E trocar a consulta para:

var res =
    from m in MyDataContext.INSCRICAOs
    group m by m.PESSOA into p
    select new MAILINGCLONE()
    {
        idMailingTexto = idMailingTexto,
        nomPessoa = p.First().PESSOA.nomPessoa,
        eMail = p.First().PESSOA.eMail,
        flaEnviado = false
    };

Isto até que não doeu. O que dói no coração é trocar isto:

dc.MAILINGs.InsertAllOnSubmit(mails);
dc.SubmitChanges();

por isto:

foreach (MAILINGCLONE mc in mails)
{
    MAILING m = new MAILING()
    {
        idMailingTexto = mc.idMailingTexto,
        nomPessoa = mc.nomPessoa,
        eMail = mc.eMail,
        flaEnviado = mc.flaEnviado,
        codPessoa = mc.codPessoa,
        datAtualiza = DateTime.Now
    };
    dc.MAILINGs.InsertOnSubmit(m);
}
dc.SubmitChanges();
Posted in programação, web | Tagged , | 2 Comments

Resolvendo o problema da busca no DSpace

Ocorre um problema em minha instalação  do DSpace. As buscas realizadas contendo caracteres com diacríticos (acentuação e etc.) retornam resultados estranhos, pois os termos da busca ficam desfigurados. E não sou só eu que enfrento isto.

Fui escarafunchar o código fonte tentando encontrar alguma solução. Não encontrei nenhuma. Vamos apelar ao onisciente então.

Um post me chamou a atenção para a configuração do Tomcat. É necessário editar o arquivo /etc/tomcat5/server.xml de formar que o elemento Connector em questão  tenha um atributo URIEncoding=”UTF-8″.

Embora este atributo seja sempre configurado no Connector padrão , que escuta na porta 8080,  me lembrei que eu havia configurado o Tomcat para funcionar em conjunto com o Apache, através do mod_jk, na porta 8009 com o AJP Connector.

Fui verificar o arquivo server.xml e bingo! Foi só mudar de

<Connector port="8009" enableLookups="false"
    redirectPort="8080" protocol="AJP/1.3" />

para

<Connector port="8009" enableLookups="false"
    redirectPort="8080" protocol="AJP/1.3"
    URIEncoding="UTF-8" />

E a busca voltou a funcionar.

Posted in software, web | Tagged | 1 Comment

Dia do Geek!!!

Hoje é o dia do Geek.

Você sabe se é um?  Pela internet devem estar rolando vários testes para isso. Vou inventar a minha!

My home office desk

  • sabe o que é e para que serve um compilador?
  • tem que dar manutenção em todos os micros, notebooks e  roteadores da sua família, parentes e amigos não-geeks?
  • consegue listar os videogames da geração atual?
  • sabe o que é Steam?
  • ficou entusiasmado com o futuro lançamento de Cave Story para Wii?
  • um de seus celulares é um smartphone (com internet, é claro)?
  • sabe quais são as três leis da robótica?
  • sabe que existe uma quarta lei da robótica?
  • tem um blog?
  • escreve um post em seu blog sobre o dia do Geek?
  • sabe criar uma lista como esta?
  • tem, já teve ou sabe tudo sobre o iPhone? (prefiro o N95, hah!)
  • conhece o Engadget, Gizmodo, Zumo etc?
  • a palavra #fail te diz algo?
  • usa um RSS Reader para ler notícias?
  • tem sede de conhecimento, e quanto mais conhecimento adquire, mais deseja conhecer?
  • gosta de leitura, online ou não?
  • na maioria das vezes se interessa por assuntos que a maioria não tem interesse ou desconhece?
  • encontra soluções fáceis (no Google) para as coisas, por ser uma pessoa que sempre está pensando de forma acelerada na internet?
  • entende esta piada?
  • adora as tirinhas do Dilbert e XKCD?
  • leu esta lista até o fim?

Se você respondeu sim para mais da metade das perguntas, então você respondeu não para menos da metade delas! Parabéns!

Posted in vida® | Tagged , , | 5 Comments

Conseguindo a URL completa de uma página

O problema é como obter a URL completa, ou absoluta (absolute URL), em Asp.NET.

public string ObtemUrl(Control c, string relativePath)
{
    //relativePath deve conter algo como "~/meu/arquivo/no/servidor"
    return new Uri(c.Page.Request.Url, c.ResolveUrl(relativePath)).ToString();
}

A chamada fica assim:

string umaUrl = objeto.ObtemUrl(this, "~/meu/arquivo/no/servidor");

A variável umaUrl conterá algo como “http://www.example.com/meu/arquivo/no/servidor”.

Não achei nenhum modo mais simples.

Posted in programação, web | Tagged | Leave a comment

Roteador 3Com 3CRWER101U

Bom, após meu terceiro roteador DLink 514 pifar, resolvi trocar de marca. É claro que eu não tinha três roteadores, mas são os três que devo dar suporte técnico plano familiar.

Comprei agora um roteador da 3Com, modelo 3CRWER101U, pois o preço estava bem em conta, ao menos em comparação com os 3Com que eu havia visto no passado.

Roteador

A inteface de configuração é bem simples, existe a opção de se configurar um DNS para toda a rede (já coloquei o OpenDNS) e outras coisitas mais (MAC filtering etc.).

Mas notei que a navegação estava lenta. Muito lenta. Lentíssima. Coisa de navegador desistir de esperar e mostrar página de erro.

Solução? Desligar o firewall do roteador. Vamos ver se alguma atualização de firmware resolve. Bom, vivi até agora sem firewall no roteador, consigo viver mais um pouco.

Posted in cacarecos | Tagged , | 3 Comments

HttpPostedFile: IE versus Firefox

Estou aqui programando, feliz da vida, e me enviam um bug para matar.

Ao subir um arquivo em nosso sistema Asp.NET surge o erro:

"The given path's format is not supported."

ou

"Não há suporte para o formato do caminho dado."
(maldita MS por traduzir mensagens de erro)

Mas eu não conseguia reproduzir o problema de nenhuma maneira. Até testar no Internet Explorer. O método que utilizo para gravar o arquivo é este:

public string Grava(HttpPostedFile postedFile, string id)
{
    string newfilename = id + postedFile.FileName;
    string fullName = DirPath + newfilename;
    postedFile.SaveAs(fullName);

    return fullName;
}

A chamada é realizada assim, onde fupAnexo é um controle FileUpload:

string path = anexo.Grava(fupAnexo.PostedFile, guid.ToString());

O problema está nesta propriedade: postedFile.FileName. O conteúdo dela depende de qual navegador é utilizado pelo usuário.

No IE o conteúdo é o caminho completo do arquivo no computador do usuário: C:\\Pasta\\Pasta\\Macarrao\\arquivo.xis.

No Firefox apenas o nome do arquivo: arquivo.xis.

O framework deveria uniformizar o acesso aos recursos do sistema, mas aprendo cada vez mais que não dá para confiar em dados vindos do usuário nem do sistema. Não confie em nada.

Acertei o método para o que segue:

public string Grava(HttpPostedFile postedFile, string id)
{
    string[] filename = postedFile.FileName.Split('\\');
    string newfilename = id + filename[filename.Count() - 1];

    string fullName = DirPath + newfilename;
    postedFile.SaveAs(fullName);

    return fullName;
}

Falta testar o caso em que o usuário acessa o sistema a partir do Linux (ou Mac OSX) usando o Internet Explorer. Mas acho que não existam tantos loucos por aí.

Posted in programação, web | Tagged , | Leave a comment

Reintegrando um branch no SVN

No meu trabalho utilizamos o excelente Subversion já há algum tempo (nem gosto de lembrar da época de zipar aquivos, colocar em uma pasta compartilhada da rede, nomear os zips com a data, sua cópia do projeto sempre diferente das dos colegas etc e tal).

Mas só há algum tempo começamos a nos organizar um pouco melhor e utilizar o esquema de trunk, branches e tags.

E um problema surgiu ao tentarmos reintegrar um branch ao trunk:

Retrieval of mergeinfo unsupported

Que diabos é isto? Após pesquisar no oráculo descobri que se trata de uma atualização do Subversion ocorrida entre as versões 1.4 e 1.5 que adicionaram novas funcionalidades.

Entretanto, para que estas funcionalidades sejam utilizadas é necessário atualizar seu repositório através do comando svnadmin upgrade:

svnadmin upgrade caminho_do_repositorio

Feito isto, tudo ok!

Posted in programação, software | Tagged | Leave a comment

Ligando um controle à um Enum

As enumerações, ou simplesmente enums, são comumentes usados para substituir valores mágicos e deixando o código mais legível e auto-documentado.

Mas em Asp.NET, às vezes se torna necessário listar os “valores” de um enum. “Valores” está entre aspas porque não é necessariamente o valor que a gente quer ligar, pois este valor é um número inteiro.

public enum CMYK
{
    CYAN,
    MAGENTA,
    YELLOW,
    KEY
}

No caso, CYAN = 0, MAGENTA = 1 e daí em diante. Seria legal então podermos ligar (através do DataSource/DataBind) este nosso enum em um controle, por exemplo um DropDownList, que deve apresentar CYAN, MAGENTA, YELLOW e KEY como opções.

protected System.Web.UI.WebControls.DropDownList ddColorComponent;

private void Page_Load(object sender, System.EventArgs e)
{
    if(!IsPostBack)
    {
        ddColorComponent.DataSource = Enum.GetNames(typeof(CMYK));
        ddColorComponent.DataBind();
    }
}

private void ddColorComponent_SelectedIndexChanged(object sender, System.EventArgs e)
{
     Color selectedColor = (Color)Enum.Parse(ddColorComponent.SelectedValue);
}

Podemos melhorar isto e dar nomes mais descritivos aos nossos enums através de atributos:

using System.ComponentModel;

public enum CMYK
{
    [Description("Ciano")]
    CYAN,
    [Description("Magenta")]
    MAGENTA,
    [Description("Amarelo")]
    YELLOW,
    [Description("Preto")]
    KEY
}

Nesta solução, no entanto, devemos escrever o código que fornece uma lista de elementos para ser usada como DataSource. Primeiro devemos extrair o conteúdo inserido como atributo do enum através de reflection:

using System.ComponentModel;
using System.Reflection;
...
...
public static string GetDescription(Enum value)
{
    FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
    DescriptionAttribute[] attributes  = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
    return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
}

Assim é possível iterar por todos os itens do enum, criando uma lista:

public static List> GetValuesAndDescription(System.Type enumType)
{
    List> kvPairList = new List>();

    foreach (Enum enumValue in Enum.GetValues(enumType))
    {
        kvPairList.Add(new KeyValuePair(enumValue.ToString(), GetDescription(enumValue)));
    }

    return kvPairList;
}

O DataBind fica assim:

ddColorComponent.DataSource = EnumDescription.GetValuesAndDescription(typeof(CMYK));
ddColorComponent.DataTextField = "Value";
ddColorComponent.DataValueField = "Key";

Fonte: http://developcode.blogspot.com/2006/12/dropdownlists-with-enums-as-datasource.html

Posted in programação, web | Tagged | Leave a comment

O Caixeiro

Depois de Fluffy:

Posted in programação, vida® | Tagged , | Leave a comment

Gerando boletos bancários em Asp.NET – Parte I

Estou em um projeto que necessita a criação de um boleto bancário para o pagamento de um serviço. Como gerá-lo, usando o Visual Studio 2008, Crystal Reports e o Linq To Sql ?

Boleto?

Vamos primeiro entender do que é composto basicamente um boleto:

  • Banco:  quem gerencia a transação;
  • Cedente:  quem vai receber a grana;
  • Sacado:  quem paga;
  • Valor do documento: quanto será pago
  • Data de vencimento: até quando pode ser pago;
  • Modalidade:  com ou sem registro. O comum para vendas online é sem registro.  Se o sacado não pagar, a responsabilidade de correr atrás é do cedente.

A entidade que padroniza os boletos no Brasil é  a Federação Brasileira de Bancos – FEBRABAN.

Continue reading

Posted in programação, software, web | Tagged , , , , , | 13 Comments