Сопоставление функций EF Core с SQLC#

Место общения программистов C#
Ответить
Anonymous
 Сопоставление функций EF Core с SQL

Сообщение Anonymous »

Я ищу более эффективный способ получить объекты из базы данных и сопоставить их с DTO, используя методы многократного использования.
Вот мои классы базы данных

Код: Выделить всё

    public class Sign
{
public int Id { get; set; }
public string Name { get; set; } = null!;

public int? SignGroupId { get; set; }
public SignGroup SignGroup { get; set; } = null!;

public int LocationId { get; set; }
public Location Location { get; set; } = null!;

public static Expression MapToDto()
{
return s => new()
{
Id = s.Id,
Name = s.Name ?? "",

//this call works as I would expect by translating into SQL and executing it at the
//database level.
Signs = s.SignGroup.Signs.Where(ss => ss.Id != s.Id)
.AsQueryable().Select(MapToGroupSignDto()).ToList(),

//This call will end up bringing the whole Location object into memory and then
//perform the mapping from memory.
LocationInfo = Location.MapToSignLocationDto()
.Compile().Invoke(s.Location),
};
}

public static Expression MapToGroupSignDto()
{
return gs => new()
{
Id = gs.Id,
Name = gs.Name ?? "",
};
}
}

public class SignGroup
{
public int Id { get; set; }
public List Signs { get; set; } = null!;
}

public class Location
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public string? Latitude { get; set; }
public string? Longitude { get; set; }
public string? State { get; set; }
public string? City { get; set; }
public string? Zip { get; set; }
public string? StreetAddress { get; set; }

public static Expression MapToSignLocationDto()
{
return l => new()
{
Id = l.Id,
Name = l.Name,
Latitude = l.Latitude ?? "",
Longitude = l.Longitude ?? "",
};
}
}
Вот мои объекты DTO:

Код: Выделить всё

 public record SignDTO
{
public int Id { get; set; }
public string Name { get; set; } = null!;

public int SignGroupId { get; set; }
[Comment("Signs At Same Location")]
public List AdditionalSings { get; set; } = null!;

public SignLocationDTO LocationInfo { get; set; } = null!;
}

public record GroupSignDTO
{
public int Id { get; set; }
public string Name { get; set; } = null!;
}

public record LocationDTO
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public string Latitude { get; set; } = null!;
public string Longitude { get; set; } = null!;
}

Вот моя серия вызовов функций в том виде, в котором они существуют сейчас. Я знаю, что функции выражений повторяются в своих вышеприведенных классах, но мне хотелось, чтобы их было легче понять.

Код: Выделить всё

public async Task GetListDataAsync()
{
IQueryable signIQ = _context.Signs;
Queryable dtoIQ = signIQ.Select(Sign.MapToDto());

return await dtoIQ.ToListAsync();
}

public static Expression MapToDto()
{
return s => new()
{
Id = s.Id,
Name = s.Name ?? "",

//this call works as I would expect by translating into SQL and executing it at the
//database level.
Signs = s.SignGroup.Signs.Where(ss => ss.Id != s.Id)
.AsQueryable().Select(MapToGroupSignDto()).ToList(),

//This call will end up bringing the whole Location object into memory and then
//perform the mapping from memory.
LocationInfo = Location.MapToSignLocationDto()
.Compile().Invoke(s.Location),
};
}

public static Expression MapToGroupSignDto()
{
return gs => new()
{
Id = gs.Id,
Name = gs.Name ?? "",
};
}

public static Expression MapToSignLocationDto()
{
return l => new()
{
Id = l.Id,
Name = l.Name,
Latitude = l.Latitude ?? "",
Longitude = l.Longitude ?? "",
};
}
Я надеюсь найти, если это возможно, простой, но в то же время лучший способ получить LocationInfo, который поместил бы весь вызов в SQL и позволил бы базе данных возвращать только то, что я действительно нужно, не заставляя SQL выполняться вечно. Мне не нравится идея, когда база данных возвращает всю информацию, связанную с местоположением, а затем сервер использует память, чтобы сопоставить ее с тем, что мне действительно нужно.
Я пробовал разные разные способов сделать это, но единственный способ добиться того, что я хотел, — это поместить весь код в одну функцию-выражение, например:

Код: Выделить всё

public static Expression MapToDto()
{
return s => new()
{
Id = s.Id,
Name = s.Name ?? "",

Signs = s.SignGroup.Signs.Where(ss => ss.Id != s.Id)
.Select(gs => new()
{
Id = gs.Id,
Name = gs.Name ?? "",
).ToList(),

LocationInfo = new()
{
Id = s.Location.Id,
Name = s.Location.Name,
Latitude = s.Location.Latitude ?? "",
Longitude = s.Location.Longitude ?? "",
},
};
}

Моя проблема заключается в том, что код нельзя повторно использовать в других областях, и для сохранения любых будущих изменений мне придется посещать несколько мест.
Будем очень признательны за любую помощь и идеи в этой области.
Спасибо :)

Подробнее здесь: https://stackoverflow.com/questions/784 ... ore-to-sql
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»