使用常见的linq表达式来避免实体重复到poco

时间:2017-05-16 12:22:27

标签: linq linq-to-entities

如何避免复制用于将数据库实体映射到poco对象的代码?

鉴于此代码:

private IQueryable<DummyExtended> Find()
{
    return (from dt in Entities.dummy_table
            select new DummyExtended
            {                           
                Description = dt.table_1.table_2.description,               
                Dummy = new Dummy 
                {
                    Name = d.name,
                    Notes = d.notes,
                    HelpText = d.help_text          
                }
            }).AsQueryable();

}

我可以创建一个共同的linq表达式来重用这两种方法吗?

private IQueryable<DummyExtended> Find()
{
    return (from dt in Entities.dummy_table
            select new DummyExtended
            {                           
                Description = dt.table_1.table_2.description,               
                Dummy = ...???
            }).AsQueryable();

}

private IQueryable<DummyAlsoExtended> FindAnother()
{
    return (from dt in Entities.dummy_table
            select new DummyAlsoExtended
            {                           
                InnerHtml = dt.table_html.description,              
                Dummy = ....??
            }).AsQueryable();

}

示例:

public static Expression<Func<dummy_table, Dummy>> EntityToPoco()
{
    return d => new Dummy 
    {
        Name = d.name,
        Notes = d.notes,
        HelpText = d.help_text
};

}

我无法正确理解

....
Dummy = ExtensionClass.EntityToPoco()

1 个答案:

答案 0 :(得分:0)

所以你有一个dummy_table,它是一个Enumerable或Queryable对象序列。假设序列包含类DummyTableElement的对象。

你表明,如果你有DummyTableElement,你知道如何将它转换为Dummy对象。您希望重用此函数来创建其他对象,例如DummyExtendedDummyAlsoExtended。如果你想做这样的LINQ,最好为它创建扩展函数:

static class DummyTableElementExtensions
{
    public static Dummy ToDummy(this TableElement tableElement)
    {
        return new Dummy()
        {
             Name = tableElement.name,
             Notes = tableElement.notes,
             HelpText = tableElement.help_text     
        };
    }
}

完成此操作后,您可以创建类似的功能,将TableElements转换为DummyExtendedDummyAlsoExtended。他们将是一个单行。

在相同的扩展类中:

public static DummyExtended ToDummyExtended(this TableElement tableElement)
{
    return new DummyExtended()
    {
        Description = tableElement.table_1.table_2.description, 
        Dummy = tableElement.ToDummy(),              
    };
}
public static DummyAlsoExtended ToDummyAlsoExtended(this TableElement tableElement)
{
    return new DummyAlsoExtended
    {                           
        InnerHtml = tableElement.table_html.description,              
        Dummy = tableElement.ToDummy(),
    };
}

一旦你有了这些,你可以创建扩展函数来转换任何IQueryable TableElements

public static IQueryable<DummyExtended> ToDummyExtended(
    this IQueryable<TableElement> tableElements)
{
    return tableElements
        .Select(tableElement => tableelement.ToDummyExtended();
}

DummyAlsoExtended的类似单行函数。

您的Find功能和FindAnother功能也将是单行:

private IQueryable<DummyExtended> Find()
{
    return dummy_table.ToDummyExtended();
}

private IQueryable<DummyAlsoExtended> FindAnother()
{
    return dummy_table.ToDummyAlsoExtended();
}

我不确定你为什么要在这里使用表达式。 DummyExtendedDummyAlsoExtended似乎并不相似,只是它们都有属性Dummy

参数化find函数的目标的一个原因可能是因为您想在Find函数中创建匿名类。

同样,一旦你创建了ToDummy,这将是一个单行:

public static IQueryable<TResult> Find<TSource, TResult>(
    this IQueryable<TSource> source,
    Expression<Func<TSource, TResult>> resultSelector)
{
    return source.Select(sourceElement => resultSelector(sourceElement);
}

用法是:

var X = dummy_Table.find(tableElement => new
   {
      foo = tableElement.CalculateFoo(),
      bar = tableElement.CalculateBar(),
      Dummy = tableElement.ToDummy(),
   });